<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>geeks have feelings &#187; Work</title>
	<atom:link href="http://www.geekshavefeelings.com/posts/category/all/work/feed" rel="self" type="application/rss+xml" />
	<link>http://www.geekshavefeelings.com</link>
	<description>xo wang</description>
	<lastBuildDate>Thu, 29 Dec 2011 20:44:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Bringing up Corntroller</title>
		<link>http://www.geekshavefeelings.com/posts/bringing-up-corntroller</link>
		<comments>http://www.geekshavefeelings.com/posts/bringing-up-corntroller#comments</comments>
		<pubDate>Sat, 22 Oct 2011 18:36:33 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Corntroller]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[chibios]]></category>
		<category><![CDATA[corntroller]]></category>
		<category><![CDATA[elec.engr]]></category>
		<category><![CDATA[stm32]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=984</guid>
		<description><![CDATA[I compensate for my engineering mistakes with bigger engineering mistakes. -Me Every new board needs an &#8220;LED blink&#8221; program. It&#8217;s basically a Hello, world! for embedded engineers. Thing is, I put two seven-segment LED arrays on Corntroller, my brushless motor controller, so my LED blink program got a little bit fan-çay: The displays were the [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>I compensate for my engineering mistakes with bigger engineering mistakes. -Me</p></blockquote>
<p>Every new board needs an &#8220;LED blink&#8221; program. It&#8217;s basically a <a href="http://en.wikipedia.org/wiki/Hello_world_program" title="Hello, World!" target="_blank">Hello, world!</a> for embedded engineers. Thing is, I put two seven-segment LED arrays on <a href="http://www.geekshavefeelings.com/posts/category/all/work/corntroller" title="Corntroller" target="_blank">Corntroller</a>, my brushless motor controller, so my LED blink program got a little bit fan-çay:</p>
<p><iframe width="640" height="360" src="http://www.youtube.com/embed/r41xsRYGjas?rel=0&amp;hd=1" frameborder="0" allowfullscreen></iframe></p>
<p>The displays were the first things I wanted to program anyways (USB is next). Among other things, you can display hexadecimal digits on them, which is pretty straightforward from a code perspective:</p>
<pre class="brush: cpp; title: ; notranslate">static struct SevenSegmentDisplay {
public:
	SevenSegmentDisplay(GPIO_TypeDef *gpio, uint8_t offset) :
			gpio(gpio), offset(offset) {
	}

	void showHex(uint8_t x) {
		palClearPort(gpio, 0xF7 &lt;&lt; offset);
		palSetPort(gpio, charLUT[x % 16] &lt;&lt; offset);
	}

	void setDP(bool dp) {
		palWritePad(gpio, offset + 3, dp);
	}

protected:
	GPIO_TypeDef * const gpio;
	const uint8_t offset;

	static const uint8_t charLUT[16];
} red(GPIOD, 8), green(GPIOE, 0);

const uint8_t SevenSegmentDisplay::charLUT[16] = {
		0x77, 0x14, 0xB3, 0xB6,
		0xD4, 0xE6, 0xE7, 0x34,
		0xF7, 0xF6, 0xF5, 0xC7,
		0x63, 0x97, 0xE3, 0xE1
};</pre>
<p>Making that lookup table was the hardest part. Most code is written for &#8220;abcdefg&#8221; bit order, but my LEDs were bit-swizzled since I rearranged my lines to have a cleaner layout. This just meant I needed different bit patterns:</p>
<p><code>// - GFABPCDE<br />
// 0 01110111<br />
// 1 00010100<br />
// 2 10110011<br />
// 3 10110110<br />
// 4 11010100<br />
// 5 11100110<br />
// 6 11100111<br />
// 7 00110100<br />
// 8 11110111<br />
// 9 11110110<br />
// A 11110101<br />
// b 11000111<br />
// C 01100011<br />
// d 10010111<br />
// E 11100011<br />
// F 11100001</code></p>
<p>For a clean layout, it&#8217;s totally worth it.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/sevenseg.png"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/sevenseg-640x504.png" alt="" title="Lines of awesome" width="640" height="504" class="alignnone size-large wp-image-990" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/bringing-up-corntroller/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Assembly-izing Tassel</title>
		<link>http://www.geekshavefeelings.com/posts/assembly-izing-tassel</link>
		<comments>http://www.geekshavefeelings.com/posts/assembly-izing-tassel#comments</comments>
		<pubDate>Thu, 20 Oct 2011 05:19:30 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Corntroller]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[corntroller]]></category>
		<category><![CDATA[elec.engr]]></category>
		<category><![CDATA[stm32]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=938</guid>
		<description><![CDATA[Tasssel: the extra &#8216;s&#8217; is for &#8220;scattering&#8221; Work continues on Corntroller, my vaguely retarded version of Shane&#8217;s sweet brushless motor controller. I got my Digi-Key order last week and started assembling the board at the Graphics/Visualization/Usability (GVU) Prototyping Lab, the sister lab to the Georgia Tech Invention Studio1, and home to my favorite hot-air reflow [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>Tasssel: the extra &#8216;s&#8217; is for &#8220;scattering&#8221;</p></blockquote>
<p>Work continues on <a href="http://www.geekshavefeelings.com/posts/corn-troller-tassel" title="Corn-Troller: Tassel">Corntroller</a>, my vaguely retarded version of <a href="http://scolton.blogspot.com/search/label/3ph" title="Shane's 3ph duo v3" target="_blank">Shane&#8217;s sweet brushless motor controller</a>.</p>
<p>I got my Digi-Key order last week and started assembling the board at the <a href="https://wiki.cc.gatech.edu/gvu/index.php/PrototypingLab" title="GVU Prototyping Lab" target="_blank">Graphics/Visualization/Usability (GVU) Prototyping Lab</a>, the sister lab to the <a href="http://inventionstudio.gatech.edu/" title="Invention Studio" target="_blank">Georgia Tech Invention Studio</a><sup><a href="http://www.geekshavefeelings.com/posts/assembly-izing-tassel#footnote_0_938" id="identifier_0_938" class="footnote-link footnote-identifier-link" title="At least in sweet, sweet funding">1</a></sup>, and home to my favorite hot-air reflow station on campus for prototyping.</p>
<p>Now the thing about reflow soldering is that it perfectly captures the sights, sounds, and smells of hell.</p>
<p>What else but hell would make you sit in place, hunched over for hours, as electric fire brings tears to your eyes and solder paste brimstone pierces your nostrils? Bright incandescent lighting, smoldering soldering irons, and in the case of the GVU reflow station, a 50-decibel electric pump all magnify the feeling of burning alive in invidious flames of divine wrath.</p>
<p><iframe width="640" height="360" src="http://www.youtube.com/embed/fyt_DEAbSOU?rel=0&amp;hd=1" frameborder="0" allowfullscreen></iframe></p>
<p>But the GVU version of surface mount hell is actually pretty legit. The aforementioned electric pump is hooked up to a precision solenoid valve gas dispenser (controlled by a foot pedal), which in turn feeds pressurized air into a hand-held tube of leaded solder paste. Hit the foot pedal, and a small and carefully controlled bit of gray goop flows out.</p>
<p>The setup basically lets you do manual pick and place assembly. Less efficient for small and medium runs than <a href="http://www.sparkfun.com/tutorials/58" title="Sparkfun Solder Paste Stenciling tutorial" target="_blank">solder paste stenciling</a>, but way less setup time and a lot more fun<sup><a href="http://www.geekshavefeelings.com/posts/assembly-izing-tassel#footnote_1_938" id="identifier_1_938" class="footnote-link footnote-identifier-link" title="No, not really">2</a></sup>. It&#8217;s perfect for prototyping a new board.</p>
<p>Now I ended up shooting video instead of taking too many pictures, so bear with my video screenshots here.</p>
<p>To make life easier, I assemble components under a 10×/30× stereo microscope with tweezers in one hand, solder paste dispenser in the other, and foot on the foot pedal.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/microscope_pnp.jpg"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/microscope_pnp-640x360.jpg" alt="" title="Microscope pick&#039;n&#039;place (you totally can&#039;t see my new faux hawk in this photo)" width="640" height="360" class="alignnone size-large wp-image-944" /></a></p>
<p>At 10× you can see the particles in the solder paste.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01646.jpg"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01646-640x425.jpg" alt="" title="7-segment closeup, unreflown" width="640" height="425" class="alignnone size-large wp-image-947" /></a></p>
<p>After assembly, I preheat the board over a <a href="http://www.zeph.com/smdpreheater.htm" title="No One Knows More About Preheating PCB's Than Zephyrtronics!" target="_blank">Zephyrtronics&#8230; board preheater</a>.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/board_preheater.jpg"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/board_preheater-640x360.jpg" alt="" title="Its uses include, and is limited to, board preheating" width="640" height="360" class="alignnone size-large wp-image-949" /></a></p>
<p>I&#8217;m not even making this up. This thing emulates the flat &#8220;warm-up&#8221; period of the reflow temperature profile you&#8217;d use in a full reflow oven. In addition, it has a <em>genius</em> &#8220;cool&#8221; mode during which it draws air down (instead of blowing hot air up), using ambient air to cool the board (&#8220;ramp-down&#8221;). No more blowing on the board until your face is red and your tongue is covered with flakes of solder.</p>
<p><a href="http://www.allegromicro.com/en/corporate/environment/faqs.asp#Q14"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/pbReflowProfile.gif" alt="" title="Allegro&#039;s recommended reflow profile" width="508" height="283" class="alignnone size-full wp-image-950" /></a></p>
<p>It even comes with a sweet PCB jig to hold your board at just the right height above the pre-heater.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01636.jpg"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01636-640x425.jpg" alt="" title="Preheat" width="640" height="425" class="alignnone size-large wp-image-948" /></a></p>
<p>After that, you pretty much just apply heat like a normal person.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/hotairgun.jpg"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/hotairgun-640x360.jpg" alt="" title="Lefrowing" width="640" height="360" class="alignnone size-large wp-image-951" /></a></p>
<p>You may notice that in addition to unpopulated inertial sensors, there are also two funny-looking solder bridges.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/ze_germans.jpg"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/ze_germans-640x425.jpg" alt="" title="Laßt uns froh sein!" width="640" height="425" class="alignnone size-large wp-image-952" /></a></p>
<p>You have ze Germans to blame for that. Had I the European-styled schematic symbols für a <a href="http://en.wikipedia.org/wiki/Choke_(electronics)#Common-mode_choke" title="Common mode choke" target="_blank">common-mode choke</a> ge-used, which had I the wrong orientation for the part ge-using. I think.</p>
<p>In other words, I managed to short my input power leads across a pair of inductors.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/eurotraschematic.png"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/eurotraschematic-640x373.png" alt="" title="eurotraschematic" width="640" height="373" class="alignnone size-large wp-image-963" /></a></p>
<p>Not that that surprises me in the least; I&#8217;ve managed to build almost every circuit I&#8217;ve ever designed to have a short from power to ground. Heck, this is the probably the highest impedance short I&#8217;ve gotten on a first-try board in the past two years.</p>
<p>Actually, maybe the footprint I was using for my <a href="http://katalog.we-online.de/kataloge/eisos/media/pdf/744232261.pdf" title="WE-CNS_1206" target="_blank">Würth-Elektronik common-mode choke</a> just had a mistake in pin assignments. But I like to chalk it up to cultural differences, since it&#8217;s 34% more hilarious that way.</p>
<p>At any rate, I ended up skipping the choke completely using solder bridges; I get less noise immunity, but hey, nobody&#8217;s perfect and I&#8217;m not sure if it would&#8217;ve even helped at all.</p>
<p>At this point, it was time to try out the logic power supply. With fingers crossed, I hook up the bench power supply to the <em>V+</em> and <em>V-</em> power pads and hit the switch.</p>
<p>Nothing.</p>
<p>Turns out when soldering leads to the V- pad while &#8220;e-testing&#8221; the board, I had broken one of the traces from the pad.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01649.jpg"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01649-640x425.jpg" alt="" title="Oops" width="640" height="425" class="alignnone size-large wp-image-954" /></a></p>
<p>Oops.</p>
<p>I haven&#8217;t made a soldering boo-boo this bad in years, but whatever. I briefly considered running a little green wire over the trace<sup><a href="http://www.geekshavefeelings.com/posts/assembly-izing-tassel#footnote_2_938" id="identifier_2_938" class="footnote-link footnote-identifier-link" title="I hear in some Asian electrical engineering tria- circles, using more than 三 (3) little green wires is a shame to the engineer&amp;#8217;s family and results in decapita- ritual de-accreditation">3</a></sup>, but then realized that I tented over all my vias with soldermask<sup><a href="http://www.geekshavefeelings.com/posts/assembly-izing-tassel#footnote_3_938" id="identifier_3_938" class="footnote-link footnote-identifier-link" title="Yeah. On a first-version prototype. Balls, suckas.">4</a></sup> and couldn&#8217;t airwire even if I wanted to.</p>
<p>Instead I just ripped up the soldermask with an X-acto knife under 30× magnification and then solder bridged the shorn copper. <em>Like a boss.</em></p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01651.jpg"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01651-300x199.jpg" alt="" title="Scrape scrape scrape" width="300" height="199" class="alignnone size-medium wp-image-955" /></a> <a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01652.jpg"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01652-300x199.jpg" alt="" title="Solder solder solder" width="300" height="199" class="alignnone size-medium wp-image-956" /></a></p>
<p>Now I was getting a sweet 3.304V out of my LT3970 circuit from an input of 4V all the way up to 31V, which was as high as the power supply could go. Not really sure why this mattered, since I&#8217;ll always be putting 5V into the board, but whatever.</p>
<p>But why the heck am I posting about such minor minutiae as fixing a broken trace when I should be plopping down code like a pro? Well, because performing board bringup<sup><a href="http://www.geekshavefeelings.com/posts/assembly-izing-tassel#footnote_4_938" id="identifier_4_938" class="footnote-link footnote-identifier-link" title="&amp;#8220;Performing board bringup&amp;#8221; sounds way cooler than &amp;#8220;bringing up&amp;#8221;">5</a></sup> on an STM32-based board like this is an (necessary) act of distilled masochism, and I avoid it like a plague even when I&#8217;m already <em>working on the board to begin with</em>. I mean, hell, the software you use with the popular GCC/GDB ARM toolchain is called <a href="http://openocd.sourceforge.net/" title="OpenOCD" target="_blank">OpenOCD</a>.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/openocd.png"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/openocd-640x335.png" alt="" title="Open... OCD?" width="640" height="335" class="alignnone size-large wp-image-958" /></a></p>
<p>So I plug my board into my <a href="http://www.olimex.com/dev/arm-usb-tiny-h.html" title="ARM-USB-TINY-H" target="_blank">Olimex ARM-USB-TINY-H</a> and then pray to Tony Stark to guide my board to a successful JTAG interrogation.</p>
<pre>C:\Users\Xo>"C:\Program Files (x86)\OpenOCD-0.4.0\bin\openocd.exe" -f interface\olimex-arm-usb-tiny-h.cfg -f target\stm32.cfg
Open On-Chip Debugger 0.5.0-dev-00753-g422e9f9-dirty (2011-02-14-13:06)
Licensed under GNU GPL v2
For bug reports, read

http://openocd.berlios.de/doc/doxygen/bugs.html

Info : only one transport option; autoselect 'jtag'
1000 kHz
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
Info : device: 6 "2232H"
Info : deviceID: 364511274
Info : SerialNumber: OLTQ5QMÖA
Info : Description: Olimex OpenOCD JTAG ARM-USB-TINY-H A
Info : max TCK change to: 30000 kHz
Info : clock speed 1000 kHz
Info : JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
Info : JTAG tap: stm32.bs tap/device found: 0x06430041 (mfg: 0x020, part: 0x6430, ver: 0x0)
Warn : JTAG tap: stm32.bs       UNEXPECTED: 0x06430041 (mfg: 0x020, part: 0x6430, ver: 0x0)
Error: JTAG tap: stm32.bs  expected 1 of 5: 0x06412041 (mfg: 0x020, part: 0x6412, ver: 0x0)
Error: JTAG tap: stm32.bs  expected 2 of 5: 0x06410041 (mfg: 0x020, part: 0x6410, ver: 0x0)
Error: JTAG tap: stm32.bs  expected 3 of 5: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)
Error: JTAG tap: stm32.bs  expected 4 of 5: 0x06414041 (mfg: 0x020, part: 0x6414, ver: 0x0)
Error: JTAG tap: stm32.bs  expected 5 of 5: 0x06418041 (mfg: 0x020, part: 0x6418, ver: 0x0)
Error: Trying to use configured scan chain anyway...
Warn : Bypassing JTAG setup events due to errors
Info : stm32.cpu: hardware has 6 breakpoints, 4 watchpoints</pre>
<p>&#8220;hardware has 6 breakpoints, 4 watchpoints&#8221; is actually what I expect to see, making this by far my most successful board bringup to date. But wait, what are those errors? Why isn&#8217;t my device (<code>0x06430041</code>) being recognized? Let&#8217;s take a look at the <code>stm32.cfg</code> script:</p>
<pre class="brush: bash; first-line: 43; highlight: [43,44]; title: ; notranslate">    # See STM Document RM0008
    # Section 29.6.2
    # Low density devices, Rev A
    set _BSTAPID1 0x06412041
    # Medium density devices, Rev A
    set _BSTAPID2 0x06410041
    # Medium density devices, Rev B and Rev Z
    set _BSTAPID3 0x16410041
    # High density devices, Rev A
    set _BSTAPID4 0x06414041
    # Connectivity line devices, Rev A and Rev Z
    set _BSTAPID5 0x06418041</pre>
<p>Oops, my STM32F103VG XL-density microcontroller isn&#8217;t in there. The comments mention Section 29.6.2 of RM0008, the STM32F1x Family Reference Manual. In section 31.6.2 (dotdotdot) of the <a href="http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf" title="Reference manual" target="_blank">newest version of RM0008</a><sup><a href="http://www.geekshavefeelings.com/posts/assembly-izing-tassel#footnote_5_938" id="identifier_5_938" class="footnote-link footnote-identifier-link" title="As of 2011/10/19">6</a></sup>, we see that <code>0x06430041</code> is Revision A of XL-density devices.</p>
<p>So I need a more recent version of OpenOCD that has the newer STM32 devices. Crap.</p>
<p>See, I use the default vanilla FTDI drivers for my Olimex, presumably so I can use the Virtual COM Port driver for the broken-out UART the ARM-USB-TINY-H doesn&#8217;t have. Yeah, I&#8217;m dumb. But OpenOCD doesn&#8217;t support those drivers out of the box; licensing issues prevent binary distributors like <a href="http://www.freddiechopin.info/index.php/en/download/category/4-openocd" title="Freddie Chopin's OpenOCD builds" target="_blank">Freddie Chopin</a> from making available binaries compatible with regular FTDI drivers. Instead most people use <a href="http://www.intra2net.com/en/developer/libftdi/" title="libftdi" target="_blank">libftdi</a> and <a href="http://www.libusb.org/wiki/libusb-win32" title="libusb-win32" target="_blank">libusb-win32</a> for hardware interfacing on Windows.</p>
<p>So I gotta build OpenOCD myself to make it work? God damn it; what is this, Linux?</p>
<p>Let&#8217;s just say <code>$ ./configure --prefix=/cygdrive/c/Users/Xo/Desktop/ocd-build/out --enable-maintainer-mode --disable-werror --disable-shared --enable-ft2232_ftd2xx --with-ftd2xx-win32-zipdir=/cygdrive/c/Users/Xo/Desktop/ocd-build/ftd2xx CC="gcc -mno-cygwin"</code><sup><a href="http://www.geekshavefeelings.com/posts/assembly-izing-tassel#footnote_6_938" id="identifier_6_938" class="footnote-link footnote-identifier-link" title="Yeah, that really is for my benefit only. How did you guess?">7</a></sup></p>
<p>With my new OpenOCD <code>0.6.0-dev</code> build, I got a fully successful JTAG scan, and the OpenOCD GDB server is now open for business:</p>
<pre>C:\Users\Xo>openocd -c "gdb_port 2222" -c "telnet_port 4444" -f "C:/Progra~2/OpenOCD/interface/olimex-arm-usb-tiny-h.cfg" -f "C:/Progra~2/OpenOCD/target/stm32f1x.cfg"
Open On-Chip Debugger 0.6.0-dev (2011-10-19-22:04)
Licensed under GNU GPL v2
For bug reports, read

http://openocd.sourceforge.net/doc/doxygen/bugs.html

Info : only one transport option; autoselect 'jtag'
1000 kHz
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
cortex_m3 reset_config sysresetreq
Info : device: 6 "2232H"
Info : deviceID: 364511274
Info : SerialNumber: OLTQ5QMÖA
Info : Description: Olimex OpenOCD JTAG ARM-USB-TINY-H A
Info : max TCK change to: 30000 kHz
Info : clock speed 1000 kHz
Info : JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
Info : JTAG tap: stm32.bs tap/device found: 0x06430041 (mfg: 0x020, part: 0x6430, ver: 0x0)
Info : stm32.cpu: hardware has 6 breakpoints, 4 watchpoints</pre>
<p>lol @ <code>C:/Progra~2</code>. Because this thing <em>f—ing breaks</em> if I don&#8217;t.</p>
<ol class="footnotes"><li id="footnote_0_938" class="footnote">At least in sweet, sweet <a href="http://support.cc.gatech.edu/resources/technology-fees/tech-fee.inventionlab.2.pdf" title="Tech Fee request" target="_blank">funding</a></li><li id="footnote_1_938" class="footnote">No, not really</li><li id="footnote_2_938" class="footnote">I hear in some Asian electrical engineering <del datetime="2011-10-20T03:21:26+00:00">tria-</del> circles, using more than 三 (3) little green wires is a shame to the engineer&#8217;s family and results in <del datetime="2011-10-20T03:21:26+00:00">decapita-</del> ritual de-accreditation</li><li id="footnote_3_938" class="footnote">Yeah. On a first-version prototype. <em>Balls</em>, suckas.</li><li id="footnote_4_938" class="footnote">&#8220;Performing board bringup&#8221; sounds way cooler than &#8220;bringing up&#8221;</li><li id="footnote_5_938" class="footnote">As of 2011/10/19</li><li id="footnote_6_938" class="footnote">Yeah, that really is for my benefit only. How did you guess?</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/assembly-izing-tassel/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Corn-Troller: Tassel</title>
		<link>http://www.geekshavefeelings.com/posts/corn-troller-tassel</link>
		<comments>http://www.geekshavefeelings.com/posts/corn-troller-tassel#comments</comments>
		<pubDate>Wed, 12 Oct 2011 09:23:33 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Corntroller]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[corntroller]]></category>
		<category><![CDATA[elec.engr]]></category>
		<category><![CDATA[ev]]></category>
		<category><![CDATA[stm32]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=920</guid>
		<description><![CDATA[Looking around at the hoppin&#8217; electric vehicle scene happening at certain institutions, I realized that pretty soon I&#8217;d be playing catch-up to more than just Jamo when it comes stuff-strutting unless I started building something ridiculous, and quickly too. So in typical son-of-an-accountant behavior, instead of building my own scooter, I decided to go the [...]]]></description>
			<content:encoded><![CDATA[<p>Looking around at the <a href="http://www.youtube.com/watch?v=b4W3iYRPeX4?hd=1" target="_blank">hoppin&#8217; electric vehicle scene</a> happening at <a title="GT Invention Studio" href="http://inventionstudio.gatech.edu/" target="_blank">certain</a> <a title="MITERS" href="http://miters.mit.edu/" target="_blank">institutions</a>, I realized that pretty soon I&#8217;d be playing catch-up to more than just <a href="http://thevariableconstant.blogspot.com/" target="_blank">Jamo</a> when it comes stuff-strutting unless I started building something ridiculous, and quickly too.</p>
<p>So in typical son-of-an-accountant behavior, instead of building my own scooter, I decided to go the manic whacky sneaky route and build something to sell to the scooter builders. So now I&#8217;m announcing the corniest, trolliest brushless motor controller of them all: <em>Corntroller</em>.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/corntroller_text.jpg"><img class="alignnone size-large wp-image-922" title="Corntroller" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/corntroller_text-640x425.jpg" alt="" width="640" height="425" /></a></p>
<p>Corntroller is a result of me completely ripping off <a title="Shane's motor controllers" href="http://scolton.blogspot.com/p/motor-controllers.html" target="_blank">Shane Colton</a> and <a title="Dan's Brushless DC motor controller board" href="http://danstrother.com/2011/01/12/brushless-dc-motor-controller-board/" target="_blank">Dan Strother</a> to build an extremely feature-bloated brushless motor controller. All of the following will be devoted to driving just a single motor:</p>
<ul>
<li>Modular corn-inspired design, stacking a logic board (called <em>Tassel</em>) onto a power board (called <em>HexHusk</em>)</li>
<li>10V–45V operation with two switching regulators for logic power (<a title="LT3991" href="http://www.linear.com/product/LT3991" target="_blank">LT3991-5</a>, <a title="LT3970" href="http://www.linear.com/product/LT3970" target="_blank">LT3970-3.3</a>)</li>
<li>At least 40A of current capacity through <a title="GWM160-0055X1" href="http://ixdev.ixys.com/DataSheet/GWM160-0055X1.pdf" target="_blank">IXYS GWM160-0055X1</a> 3-phase MOSFET power modules</li>
<li>Way too much processing power from a 100-pin <a title="STM32F103VG" href="http://www.st.com/internet/mcu/product/247492.jsp" target="_blank">STM32F103VG</a>, one of the top parts in the STM32 F1 series of ARM Cortex M3 microcontrollers</li>
<li>Full voltage and current sensing on everything (motor phases and power bus), so I can implement vector control or sensorlessness</li>
<li>Compact three-phase N-channel FET driving through dedicated gate driver IC (<a href="http://www.allegromicro.com/en/Products/Part_Numbers/4935/" target="_blank">A4935</a>)</li>
<li>Motor hall sensor inputs to microcontroller capture timer</li>
<li>microSD card slot interfaced through SDIO (not MMC over SPI) for <a title="*cough*" href="http://scolton.blogspot.com/2010/09/midi-for-your-motor.html" target="_blank">datalogging</a></li>
<li>Full speed USB interface&#8230; just because</li>
<li>Two 7-segment LED displays&#8230; also just because</li>
<li>Full 9-degrees-of-measure IMU (accelerometer, gyroscope, magnetometer) with the some of the best dumb<sup><a href="http://www.geekshavefeelings.com/posts/corn-troller-tassel#footnote_0_920" id="identifier_0_920" class="footnote-link footnote-identifier-link" title="Read: non-intelligent, where &amp;#8220;intelligent&amp;#8221; is a technical term">1</a></sup> MEMS sensors (<a href="http://www.bosch-sensortec.com/content/language1/downloads/BST-BMA180-FL000-03.pdf" title="BMA180" target="_blank">BMA180</a>, <a href="http://invensense.com/mems/gyro/tripleaxis.html" title="IMU3000" target="_blank">IMU3000</a>, <a href="http://www.magneticsensors.com/three-axis-digital-compass.php" title="HMC5883L" target="_blank">HMC5883L</a>) available&#8230; just $@#%ing because</li>
</ul>
<p>I&#8217;m only half-joking about that last one; I designed <em>Tassel</em>, the logic board on Corntroller, as a replacement for my (yet to be written up) <em>Maizure</em> Cortex M3/MEMS sensors board. Maizure has served as my general dev board, and its successor is so full featured and has such overspec&#8217;d components because of that. But, I can choose to not populate components for unused features. So when Tassel is used as a part of Corntroller, it will not have its 3-axis MEMS sensor footprints populated<sup><a href="http://www.geekshavefeelings.com/posts/corn-troller-tassel#footnote_1_920" id="identifier_1_920" class="footnote-link footnote-identifier-link" title="Or maybe it will&amp;#8230; what electric vehicle could use an IMU?  ">2</a></sup>.</p>
<p>By the way, I started naming my projects after corn. Just—you guessed it—because.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/tassel_text.jpg"><img class="alignnone size-large wp-image-923" title="Tassel" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/tassel_text-640x426.jpg" alt="" width="640" height="426" /></a></p>
<p>Tassel was laid out with only surface mount components (preferring 0603<sup><a href="http://www.geekshavefeelings.com/posts/corn-troller-tassel#footnote_2_920" id="identifier_2_920" class="footnote-link footnote-identifier-link" title="That&amp;#8217;s 6 mils by 3 mils or 0.006&Prime;&times;0.003&Prime;">3</a></sup> chip resistors and capacitors), all on the top side. Layout was actually fairly straightforward, since a lot of the work required just routing directly from STM32 pins to headers (which I could reassign anyways).</p>
<p>The hard part was figuring out which peripherals I could route <em>out of the STM32</em>. The original plan was to use a 48-pin device; this grew to 64-pin and then 100-pin as I realized that all the &#8220;good&#8221; peripherals I wanted in the STM32 were actually sharing the same pins.</p>
<p>For example, USART1 and TIM1 (with its useful three-phase complemented PWM with software deadtime insertion) shared the same pins. I had to spend a solid week assigning pins to their functionalities, restarting all over each time I had to up the pin count and move to a bigger device. Through all of this I also had to make sure to fan everything out properly so wires route cleanly from µC pin to headers and devices.</p>
<p>That&#8217;s really how I ended up with 7-segment displays; switching to 100 pins meant I had a lot of I/O pins left over that I didn&#8217;t want to go to waste. With the decimal point, each <a href="http://www.kingbrightusa.com/category.asp?catalog%5Fname=LED&#038;category%5Fname=KC0%2E2in+1%2DDigit" title="Kingbright 10-SMD ACS 7-segment LED display" target="_blank">Kingbright 0.2&#8243; display</a> fills up 8 pins: perfect for half a GPIO port, and thus nice to control in software.</p>
<p>Plus, 7-segment displays and resistor arrays are way easier to solder than individual 0805 LEDs and 0603 resistors.</p>
<p>So I ended up with a long list of nets to route well before even starting a schematic in <a title="CadSoft - EAGLE" href="http://www.cadsoftusa.com/" target="_blank">EAGLE</a> (see appendix)!</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/tassel_layout.png"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/tassel_layout-640x383.png" alt="" title="Tassel layout" width="640" height="383" class="alignnone size-large wp-image-927" /></a></p>
<p>Since Maizure had a bit of problems with noise and stability, I made Tassel a four-layer design. This means extra layers of copper on which to route signals, but more importantly to serve as ground planes for surface signals. This isn&#8217;t necessarily <em>needed</em>, but it certainly lends me extra noise immunity I figure I&#8217;d want on such a densely routed board.</p>
<p>A four-layer design meant I had way fewer choices in PCB fabrication: I went with <a title="Laen's group order" href="http://www.dorkbotpdx.org/wiki/pcb_order" target="_blank">Dorkbot Portland&#8217;s group PCB order</a>, but also considered <a title="4PCB $66 each" href="http://www.4pcb.com/index.php?load=content&amp;page_id=131" target="_blank">4PCB&#8217;s/Advanced Circuits&#8217;s $66 each service</a> and <a title="BatchPCB 4-layer" href="http://batchpcb.com/index.php/Faq#what_are_the_pcb_rules" target="_blank">BatchPCB&#8217;s 4-layer group order</a>. For me, DorkbotPDX just turned out to be the best bang for the buck.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01582.jpg"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/DSC01582-640x425.jpg" alt="" title="Tassel in the wind" width="640" height="425" class="alignnone size-large wp-image-930" /></a></p>
<p>Why do I just have photos of unpopulated boards? Because (a) they&#8217;re pretty and (b) I sent these out before I finished designing the power stage, in an attempt to pipeline the prototyping process. I wanted to send these out, complete HexHusk, order parts for both from Digi-Key, and have the components before Tassel&#8217;s boards arrived. That didn&#8217;t happen&#8230; the Digi-Key order is just now in the mail. Guess I failed at pipelining.</p>
<p>Design files for everything and a HexHusk post are coming. I promise.</p>
<p><strong>Appendix</strong><br />
Partial pin assignments:</p>
<pre>Outputs
=======
# Q1
15 PC0 V_P
16 PC1 V_A
17 PC2 V_B
18 PC3 V_C
23 PA0 I_A
24 PA1 I_B
25 PA2 I_P

# Q2
26 PA3 AN_0
29 PA4 SPI1_NSS
30 PA5 SPI1_SCK
31 PA6 SPI1_MISO
32 PA7 SPI1_MOSI
- V+
- V-

- 3.3V
39 PE8 PWM1~ # remap
40 PE9 PWM1 # remap
41 PE10 PWM2~ # remap
42 PE11 PWM2 # remap
43 PE12 PWM3~ # remap
44 PE13 PWM3 # remap

# Q3
68 PA9 USART1_TX
69 PA10 USART1_RX
# Q4
86 PD5 H1 # 5V
87 PD6 H2 # 5V
88 PD7 H3 # 5V
92 PB6 I2C1_SCL
93 PB7 I2C1_SDA

JTAG
====
- 3.3V
PB4 JTRST
PA15 JTDI
PA13 JTMS
PA14 JTCK
PB3 JTDO
NRST RESET
- V-

USB
===
PA11 USB_D-
PA12 USB_D+
- V+
- V-

SDIO
====
PC8 SDIO_D0
PC9 SDIO_D1
PC10 SDIO_D2
PC11 SDIO_D3
PC12 SDIO_CK
PD2 SDIO_CMD

MEMS
====
PB10 I2C2_SCL
PB11 I2C2_SDA
PB12 SPI2_NSS
PB13 SPI2_SCK
PB14 SPI2_MISO
PB15 SPI2_MOSI</pre>
<ol class="footnotes"><li id="footnote_0_920" class="footnote">Read: non-intelligent, where &#8220;intelligent&#8221; is a <a href="http://en.wikipedia.org/wiki/Intelligent_sensor" title="WP: Intelligent sensor" target="_blank">technical term</a></li><li id="footnote_1_920" class="footnote">Or maybe it will&#8230; what electric vehicle could use an IMU? <img src='http://www.geekshavefeelings.com/x/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </li><li id="footnote_2_920" class="footnote">That&#8217;s 6 mils by 3 mils or 0.006″×0.003″</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/corn-troller-tassel/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5V to 3.3V with Preferred Resistors</title>
		<link>http://www.geekshavefeelings.com/posts/5v-to-3-3v-with-preferred-resistors</link>
		<comments>http://www.geekshavefeelings.com/posts/5v-to-3-3v-with-preferred-resistors#comments</comments>
		<pubDate>Sun, 02 Oct 2011 00:33:26 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[elec.engr]]></category>
		<category><![CDATA[resistor]]></category>
		<category><![CDATA[resistor.divider]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=893</guid>
		<description><![CDATA[What do you do when you want to scale a 5V analog signal to 3.3V? You build a resistor divider, possibly with an op amp-based voltage follower to drive low impedance loads. But what resistors do you buy for your resistor bridge? You want resistance values of some multiple of 1.7 to 3.3, but resistors [...]]]></description>
			<content:encoded><![CDATA[<p>What do you do when you want to scale a 5V analog signal to 3.3V? You build a resistor divider, possibly with an op amp-based voltage follower to drive low impedance loads.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/microchip_en026368.pdf.png"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/10/microchip_en026368.pdf-300x152.png" alt="" title="microchip_en026368.pdf" width="300" height="152" class="alignnone size-medium wp-image-917" /></a></p>
<p>But what resistors do you buy for your resistor bridge? You <em>want</em> resistance values of some multiple of 1.7 to 3.3, but resistors come in <a title="Resistor decades" href="http://www.logwell.com/tech/components/resistor_values.html">preferred values</a>, which are mathemagicatically spaced out resistance scales.</p>
<p>None of the &#8220;nice&#8221; E24 values that are multiples of 170 or 330 really work (330 exists, but not 170; there&#8217;s a 510 but no 990; and 680 but no 1320).</p>
<p>There&#8217;s gotta be some kind of ideal combination of preferred-value resistors that give me either the perfect 5V to 3.3V divider, or at least minimizes the error. Well, I wasn&#8217;t about to do all 24² combinations of upper/lower resistors by hand and for some reason Google couldn&#8217;t find it for me, so I wrote a <del>script</del> C++0x program to uh&#8230; do it for me<sup><a href="http://www.geekshavefeelings.com/posts/5v-to-3-3v-with-preferred-resistors#footnote_0_893" id="identifier_0_893" class="footnote-link footnote-identifier-link" title="Actually, the code runs in O(N * log N) time rather than O(N&sup2;) time: given some high-side resistance, I run a binary search on which low-side resistor value gives the best divider. I loop over all high-side resistances.">1</a></sup>.</p>
<p>So what are the results for each EIA resistor value series?</p>
<pre>E12 best: r1 = 180, r2 = 330 (-5.556%)
E24 best: r1 = 470, r2 = 910 (-0.258%)
E48 best: r1 = 825, r2 = 1600 (-0.092%)
E96 best: r1 = 491, r2 = 953 (-0.012%)
E192 best: r1 = 102, r2 = 198 (+0.000%)</pre>
<p>Those error percentages are for voltage drop over the top half of the resistor divider, not for the resulting voltages. For example, the 180 &amp; 330 combo would have an error of <img src='http://s.wordpress.com/latex.php?latex=%5Cleft%28%5Cfrac%7B330%7D%7B180%20%2B%20330%7D%20%5Cdiv%20%5Cfrac%7B3.3%7D%7B5%7D%20-%201%5Cright%29%20%5Ctimes%20100%5C%25%20%3D%20-1.96%5C%25&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\left(\frac{330}{180 + 330} \div \frac{3.3}{5} - 1\right) \times 100\% = -1.96\%' title='\left(\frac{330}{180 + 330} \div \frac{3.3}{5} - 1\right) \times 100\% = -1.96\%' class='latex' />. Not bad for parts you can get at RadioShack.</p>
<p>It turns E192 does have a perfect combo, but it&#8217;s not like E192-series resistors are available from Digi-Key. However, you can get E96 resistors to build a divider with only -0.0042% error, which will have so much error due to <a href="http://www.edn.com/article/509250-7_solution.php">the bimodal distribution of binned resistor values</a> that the time you&#8217;ve spent on making it &#8220;correct&#8221; would be completely wasted.</p>
<p>Damn.</p>
<h2>Appendix: &#8216;Dat code</h2>
<pre class="brush: cpp; title: ; notranslate">
/*
 * 2011 Xo Wang
 * I hereby release this into the public domain, something about merchantability, blah blah. If you use it, it'd be nice to let me know.
 *
 * You'd be an idiot to use this; it does many things very wrong for the sake of expedient solution-getting.
 */

#include &lt;algorithm&gt; // &lt;3 lower_bound, &lt;3 set_union
#include &lt;iostream&gt;
#include &lt;limits&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

#include &lt;cstdlib&gt;

static double error(const double r1, const double r2) {
	return (r2 * 1.7) / (r1 * 3.3) - 1.0;
}

static void process_series(const std::string &amp;name, const std::vector&lt;int&gt; series) {
	using namespace std;

	int min_error_r1 = 0;
	int min_error_r2 = 0;
	double min_error = numeric_limits&lt;double&gt;::max();
	for_each(series.begin(), series.end(), [&amp;](const int r1) {
		// find nearest resistance
		const double r2_wanted = r1 * (3.3 / 1.7);
		// r_wanted is too large, so scale it down by ten when searching
		const bool r2_wanted_10x = r2_wanted &gt; series.back();
		const auto r2_higher_iter = lower_bound(series.begin(), series.end(), r2_wanted_10x ? r2_wanted * 0.1 : r2_wanted);

		// nearest two resistance values
		const int r2_higher = r2_wanted_10x ? *r2_higher_iter * 10 : *r2_higher_iter;
		const int r2_lower = [=]() -&gt; int {
			if (r2_higher == series[0] * 10) {
				return series.back();
			}
			return r2_wanted_10x ? *(r2_higher_iter - 1) * 10 : *(r2_higher_iter - 1);
		}();

		if (fabs(min_error) &gt; fabs(error(r1, r2_lower))) {
			min_error = error(r1, r2_lower);
			min_error_r1 = r1;
			min_error_r2 = r2_lower;
		}

		if (fabs(min_error) &gt; fabs(error(r1, r2_higher))) {
			min_error = error(r1, r2_higher);
			min_error_r1 = r1;
			min_error_r2 = r2_higher;
		}

		//cout &lt;&lt; &quot;  r1 = &quot; &lt;&lt; r1 &lt;&lt; &quot;, r2 = { &quot; &lt;&lt;
		//		r2_lower &lt;&lt; &quot; (&quot; &lt;&lt; error(r1, r2_lower) * 100 &lt;&lt; &quot;%), &quot; &lt;&lt;
		//		r2_higher &lt;&lt; &quot; (+&quot; &lt;&lt; error(r1, r2_higher) * 100 &lt;&lt; &quot;%) }\n&quot;;
	});

	cout &lt;&lt; name &lt;&lt; &quot; best: r1 = &quot; &lt;&lt; min_error_r1 &lt;&lt; &quot;, r2 = &quot; &lt;&lt; min_error_r2 &lt;&lt;
			&quot; (&quot; &lt;&lt; (min_error &gt; 0 ? &quot;+&quot; : &quot;&quot;) &lt;&lt; min_error * 100 &lt;&lt; &quot;%)\n&quot;;
}

static std::vector&lt;int&gt; merge_series(const std::vector&lt;int&gt; &amp;s1, const std::vector&lt;int&gt; &amp;s2) {
	using namespace std;
	vector&lt;int&gt; out_series(s1.size() + s2.size());
	auto last = set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), out_series.begin());
	out_series.resize(distance(out_series.begin(), last));
	return out_series;
}

int main() {
	using namespace std;

	const vector&lt;int&gt; E12 = { 100, 120, 150, 180, 220, 270, 330, 390, 470, 560, 680, 820 };
	const vector&lt;int&gt; E24 = { 100, 110, 120, 130, 150, 160, 180, 200, 220, 240, 270, 300, 330, 360, 390, 430, 470,
			510, 560, 620, 680, 750, 820, 910 };
	const vector&lt;int&gt; E48 = { 100, 105, 110, 115, 121, 127, 133, 140, 147, 154, 162, 169, 178, 187, 196, 205, 215,
			226, 237, 249, 261, 274, 287, 301, 316, 332, 348, 365, 383, 402, 422, 442, 464, 487, 511, 536, 562, 590,
			619, 649, 681, 715, 750, 787, 825, 866, 909, 953 };
	const vector&lt;int&gt; E96 = { 100, 102, 105, 107, 110, 113, 115, 118, 121, 124, 127, 130, 133, 137, 140, 143, 147,
			150, 154, 158, 162, 165, 169, 174, 178, 182, 187, 191, 196, 200, 205, 210, 215, 221, 226, 232, 237, 243,
			249, 255, 261, 267, 274, 280, 287, 294, 301, 309, 316, 324, 332, 340, 348, 357, 365, 374, 383, 392, 402,
			412, 422, 432, 442, 453, 464, 475, 487, 491, 511, 523, 536, 549, 562, 576, 590, 604, 619, 634, 649, 665,
			681, 698, 715, 732, 750, 768, 787, 806, 825, 845, 866, 887, 909, 931, 959, 976 };
	const vector&lt;int&gt; E192 = { 100, 101, 102, 104, 105, 106, 107, 109, 110, 111, 113, 114, 115, 117, 118, 120, 121,
			123, 124, 126, 127, 129, 130, 132, 133, 135, 137, 138, 140, 142, 143, 145, 147, 149, 150, 152, 154, 156,
			158, 160, 162, 164, 165, 167, 169, 172, 174, 176, 178, 180, 182, 184, 187, 189, 191, 193, 196, 198, 200,
			203, 205, 208, 210, 213, 215, 218, 221, 223, 226, 229, 232, 234, 237, 240, 243, 246, 249, 252, 255, 258,
			261, 264, 267, 271, 274, 277, 280, 284, 287, 291, 294, 298, 301, 305, 309, 312, 316, 320, 324, 328, 332,
			336, 340, 344, 348, 352, 357, 361, 365, 370, 374, 379, 383, 388, 392, 397, 402, 407, 412, 417, 422, 427,
			432, 437, 442, 448, 453, 459, 464, 470, 475, 481, 487, 493, 499, 505, 511, 517, 523, 530, 536, 542, 549,
			556, 562, 569, 576, 583, 590, 597, 604, 612, 619, 626, 634, 642, 649, 657, 665, 673, 681, 690, 698, 706,
			715, 723, 732, 741, 750, 759, 768, 777, 787, 796, 806, 816, 825, 835, 845, 856, 866, 876, 887, 898, 909,
			920, 931, 942, 953, 965, 976, 988 };

	cout.setf(ios::fixed, ios::floatfield);
	cout.precision(3);
	process_series(&quot;E12&quot;, E12);
	vector&lt;int&gt; series = merge_series(E12, E24);
	process_series(&quot;E24&quot;, series);
	series = merge_series(series, E48);
	process_series(&quot;E48&quot;, series);
	series = merge_series(series, E96);
	process_series(&quot;E96&quot;, series);
	series = merge_series(series, E192);
	process_series(&quot;E192&quot;, series);

	return EXIT_SUCCESS;
}
</pre>
<ol class="footnotes"><li id="footnote_0_893" class="footnote">Actually, the code runs in O(N * log N) time rather than O(N²) time: given some high-side resistance, I run a binary search on which low-side resistor value gives the best divider. I loop over all high-side resistances.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/5v-to-3-3v-with-preferred-resistors/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Still Alive</title>
		<link>http://www.geekshavefeelings.com/posts/still-alive</link>
		<comments>http://www.geekshavefeelings.com/posts/still-alive#comments</comments>
		<pubDate>Fri, 23 Sep 2011 07:11:05 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[elec.engr]]></category>
		<category><![CDATA[ev]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=885</guid>
		<description><![CDATA[No, seriously, I&#8217;m not dead.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/09/tassel.png"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/09/tassel-640x396.png" alt="" title="Tassel" width="640" height="396" class="alignnone size-large wp-image-886" /></a></p>
<p>No, seriously, I&#8217;m not dead.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/still-alive/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Glide Board Survey</title>
		<link>http://www.geekshavefeelings.com/posts/glide-board-survey</link>
		<comments>http://www.geekshavefeelings.com/posts/glide-board-survey#comments</comments>
		<pubDate>Mon, 07 Feb 2011 04:57:47 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[elec.engr]]></category>
		<category><![CDATA[gatech]]></category>
		<category><![CDATA[inventure]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=855</guid>
		<description><![CDATA[So I&#8217;m in a team for the 2011 InVenture Prize at Georgia Tech. I&#8217;d like to get some market research done for my team&#8217;s product, the Glide Board. Here&#8217;s a demo video: Here&#8217;s what the next prototype looks like. Note the compact size, the modern Bauhaus &#8220;function over form&#8221; styling, and lack of a hand [...]]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;m in a team for the <a href="http://inventureprize.gatech.edu/">2011 InVenture Prize at Georgia Tech</a>. I&#8217;d like to get some market research done for my team&#8217;s product, the Glide Board. Here&#8217;s a demo video:<br />
<iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/xvfUIxusPZw" frameborder="0" allowfullscreen></iframe></p>
<p>Here&#8217;s what the next prototype looks like. Note the compact size, the modern Bauhaus &#8220;function over form&#8221; styling, and lack of a hand controller: all control is done by <em>simply leaning</em>.<br />
<a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/02/Glider-Proto-B.8bit.png"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/02/Glider-Proto-B.8bit-640x400.png" alt="" title="Glider Prototype 2.0" width="640" height="400" class="alignnone size-large wp-image-878" /></a><br />
The final product may look even better!</p>
<p><iframe src="https://spreadsheets0.google.com/embeddedform?formkey=dFVjTE44cHItMExrbi1ld19GNkNMOWc6MQ" width="760" height="820" frameborder="0">Loading&#8230;</iframe></p>
<p>If you&#8217;re completely unsure about prices, here are some related products:</p>
<table>
</tr>
<td>
		<a href="http://www.amazon.com/EMAD-Electric-Skateboards-SS600-Skateboard/dp/B002Y7120Y"><br />
<h2><strong>$550</strong> EMAD Electric Skateboard</h2>
<p>		<img alt="" src="http://ecx.images-amazon.com/images/I/31KZ-m8UPkL._SL500_AA280_.jpg" title="EMAD"/></a>
	</td>
<td>
		<a href="http://www.amazon.com/Razor-13112430-E200-Electric-Scooter/dp/B000BYCC0Q"><br />
<h2><strong>$160</strong> Razor E200 Electric Scooter</h2>
<p>		<img alt="" src="http://ecx.images-amazon.com/images/I/41HVQRQECAL._SL500_AA280_.jpg" title="Razor E200"/></a>
	</td>
</tr>
</tr>
<td>
		<a href="http://www.amazon.com/Sector-Professional-Complete-Longboard-Skateboard/dp/B001K3D3L4"><br />
<h2><strong>$190</strong> Sector 9 Longboard</h2>
<p>		<img alt="" src="http://ecx.images-amazon.com/images/I/41pHvOGOHIL._SL500_AA280_.jpg" title="Sector 9"/></a>
	</td>
<td>
		<a href="http://www.amazon.com/Segway-i2-Personal-Transporter/dp/B0012Y5AVC"><br />
<h2><strong>$6200</strong> Segway i2 Personal Transporter</h2>
<p>		<img alt="" src="http://ecx.images-amazon.com/images/I/41VmzAnovPL._SL500_AA280_.jpg" title="Segway"/></a>
	</td>
</tr>
</tr>
<td>
		<a href="http://www.alteredelectricskateboards.com/wombat_250.htm"><br />
<h2><strong>$300</strong> Altered Wombat Electric Skateboard</h2>
<p>		<img alt="" src="http://www.alteredelectricskateboards.com/site_images/products/WOMBAT250REG.jpg" title="Altered Wombat 250" width="280"/></a>
	</td>
<td>
		<a href="http://www.alteredelectricskateboards.com/thedrop_600.htm"><br />
<h2><strong>$760</strong> Altered Drop Electric Skateboard</h2>
<p>		<img alt="" src="http://www.alteredelectricskateboards.com/site_images/products/TheDrop600ZebrawoodREG.jpg" title="Altered The Drop" width="280"/></a>
	</td>
</tr>
</table>
<p>Also check out another styling option from Jamo:<br />
<a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/02/Glider-Proto-B.jgo_.jpg"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2011/02/Glider-Proto-B.jgo_-640x360.jpg" alt="" title="Glider Prototype 2.0 Alt Style" width="640" height="360" class="alignnone size-large wp-image-879" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/glide-board-survey/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Venn Diagram (Spoiler: Quaternions)</title>
		<link>http://www.geekshavefeelings.com/posts/venn-diagram-spoiler-quaternions</link>
		<comments>http://www.geekshavefeelings.com/posts/venn-diagram-spoiler-quaternions#comments</comments>
		<pubDate>Wed, 01 Dec 2010 08:26:31 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[avionics]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[comp.sci]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[quaternions]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=829</guid>
		<description><![CDATA[I figure all geek blogs need some sort of Venn diagram to illustrate some super insightful facts of life, so I decided to go meta and do one about my interests blog. So I&#8217;m pretty sure I haven&#8217;t blogged about quaternions yet, so here goes: god damn quaternions. Also, no blood for Euler. I&#8217;m no [...]]]></description>
			<content:encoded><![CDATA[<p>I figure all geek blogs need some sort of Venn diagram to illustrate some super insightful facts of life, so I decided to go meta and do one about my <del datetime="2010-12-01T08:12:08+00:00">interests</del> blog.</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/12/VennDiagramTitle1.png"><img class="aligncenter size-large wp-image-840" title="Venn Diagram Title" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/12/VennDiagramTitle1-640x376.png" alt="" width="640" height="376" /></a></p>
<p>So I&#8217;m pretty sure I haven&#8217;t blogged about quaternions yet, so here goes: god damn quaternions.</p>
<p>Also, <em>no blood for Euler</em>. I&#8217;m no hippie, but we need to reduce our dependence on Euler angles and move on to a more modern, sustainable representation of orientation with no singularities. I&#8217;m not willing to send off young American men and women to die just for the sake of your decadent way of determining attitude.</p>
<p>Here&#8217;s a sneak preview of what I&#8217;m doing these days (besides everything else):</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/12/quatrain_sneak_lofi.png"><img class="aligncenter size-full wp-image-833" title="quatrain_sneak_lofi" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/12/quatrain_sneak_lofi.png" alt="" width="720" height="502" /></a></p>
<p>It&#8217;s a really simple simulation framework for nonlinear recursive estimation filters for attitude determination. Like &#8220;<a title="Raxo" href="http://www.geekshavefeelings.com/projects/raxo">dynamically-compiled rasterizing software renderer</a>,&#8221; this doesn&#8217;t actually mean anything, but I&#8217;m still looking for a good acronym. If I throw in &#8220;orientation,&#8221; I get enough letters for &#8220;NOFEAR,&#8221; but &#8220;nonlinear orientation filter estimation attitude recursive&#8221; makes no sense.</p>
<p>By the way, the screenshot above looks crappy because I made it look crappy; I wanted to post a second screenshot later and claim that I made mad improvements to the visualizer. It actually looked pretty decent prior to the lo-fi&#8217;ing:</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/12/quatrain_sneak_hifi.png"><img class="aligncenter size-full wp-image-835" title="quatrain_sneak_hifi" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/12/quatrain_sneak_hifi.png" alt="" width="720" height="502" /></a></p>
<p>Yeah, so I just failed at lying for fun and profit. Oh well. Though I really do need a better model for orientation visualization than the <a href="http://en.wikipedia.org/wiki/Utah_teapot">Ohio waterspout</a><sup><a href="http://www.geekshavefeelings.com/posts/venn-diagram-spoiler-quaternions#footnote_0_829" id="identifier_0_829" class="footnote-link footnote-identifier-link" title="Credit to my friend TH for the name">1</a></sup>&#8230;</p>
<p>I&#8217;ve got a big pset due in 8 hours and an exam in 6 hours, so I guess I better stop write-crastinating.</p>
<p>God damn quaternions. ♥</p>
<ol class="footnotes"><li id="footnote_0_829" class="footnote">Credit to my friend TH for the name</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/venn-diagram-spoiler-quaternions/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>HÄRDBÖRD: Interesting Bits</title>
		<link>http://www.geekshavefeelings.com/posts/hardbord-interesting-bits</link>
		<comments>http://www.geekshavefeelings.com/posts/hardbord-interesting-bits#comments</comments>
		<pubDate>Mon, 25 Oct 2010 02:05:26 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[comp.sci]]></category>
		<category><![CDATA[elec.engr]]></category>
		<category><![CDATA[gatech]]></category>
		<category><![CDATA[hardbord]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=776</guid>
		<description><![CDATA[OK, so I need to get better at blogging on caffeine. I spent about four times the amount of time writing the last blog post on HÄRDBÖRD than I did working on the stuff described in it. And let&#8217;s face it, what I described were my personal insecurities about electronics hacking becoming more popular &#38; [...]]]></description>
			<content:encoded><![CDATA[<p>OK, so I need to get better at blogging on caffeine. I spent about four times the amount of time writing the last blog post on HÄRDBÖRD than I did working on the stuff described in it. And let&#8217;s face it, what I described were my personal insecurities about electronics hacking becoming more popular &amp; accessible, making my own talents less sexy to the laywoman (and layman). That, and a ghetto DAC with three passive components hooked up. Big whoop. So here&#8217;s the next part, with actual interesting stuff.</p>
<h2>Transmitten</h2>
<p>would be a great name if my setup involved some sort of sensory glove and I hadn&#8217;t brutalized the German language, but it doesn&#8217;t and I have&#8230;</p>
<h2>The transmitter</h2>
<p>I could explain the design, but I think this video is more helpful (though not <em>very</em> helpful):</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/controllertest_720p.mp4">HÄRDBÖRD: Interesting Bits</a></p>
<p>I think it&#8217;s fairly obvious what I was trying to do here, though poor camerawork <em>cough</em>jamison<em>cough</em> kind of obscured how moving the joystick on the Nunchuk controlled Jamison&#8217;s three-pound battlebot, Cake. Wirelessly. Anyways, a series of dysconscious design decisions led to the following desired specs:</p>
<ul>
<li>Wireless control of the BÖRDs</li>
<li>Wii Nunchuk as the human interface</li>
<li>Some sort of reliable 2.4GHz link (radio hardware with a protocol stack built in)</li>
</ul>
<p>Everything else fell into place right after that. I grabbed two pairs of the lowest-end Xbee radio transceivers as well as the cheapest USB adapters and breakout boards I could find for them. &#8220;O Captain,&#8221; you cry, &#8220;that&#8217;ll be from Sparkfun, right?&#8221;</p>
<p>Yeah no, Sparkfun is for tools, man. They were so much better when they were underground. &lt;/hípster&gt;</p>
<p>Surprisingly enough, <a href="http://www.parallax.com/">Parallax</a> has Xbees at the same price as Digi-Key/Mouser, $3 breakout adapter boards<sup><a href="http://www.geekshavefeelings.com/posts/hardbord-interesting-bits#footnote_0_776" id="identifier_0_776" class="footnote-link footnote-identifier-link" title="With pin headers, Montresor! Sparkfun sells only headers at the same cost.">1</a></sup>, and a $20 USB breakout<sup><a href="http://www.geekshavefeelings.com/posts/hardbord-interesting-bits#footnote_1_776" id="identifier_1_776" class="footnote-link footnote-identifier-link" title="Really a USB to serial adapter + LDO regulator with an Xbee footprint.">2</a></sup>. And you thought they&#8217;re those overpriced backwards BASIC Stamp kids who supposedly got superseded by the Arduino clusterfugue<sup><a href="http://www.geekshavefeelings.com/posts/hardbord-interesting-bits#footnote_2_776" id="identifier_2_776" class="footnote-link footnote-identifier-link" title="OK, they are. But still. SUPPLIES!">3</a></sup>.</p>
<p>The rest of the article is about the technical hacks I used in software to reduce complexity, part count, cost, etc. Boring stuff.</p>
<h2>Nunchuk</h2>
<p>First off, it&#8217;s <em>&#8220;nunchuk</em>.&#8221; Not &#8220;nunchuck,&#8221; which is what you do in a convent.</p>
<p>Secondly, these things are an awesome addition to any project requiring an analog joystick, two buttons, and a three axis gyro, mounted in an overly ergonomic housing with Apple aesthetics and Nintendo unbreakability. Take care not to drop them though—you might break the floor. Nunchuks can be accessed through a simple I²C interface, exposed physically through six spring contacts in the connector for which <a href="http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available/">simple adapters</a> are available.</p>
<p>Keep in mind that the Nunchuks have gold-plated spring contacts and there is a tin finish on those adapters. This causes some sort of galvanic reaction and you get a lot of streaky black residue on both after a few months of use. Ew.</p>
<p>Now, I haven&#8217;t written straight C for a while now, so I wondered what sort of twisted interface code I&#8217;d come up with to grab data off of these things. Oddly enough I didn&#8217;t screw up the external interface that badly:</p>
<pre class="brush: cpp; light: true; title: ; notranslate">typedef struct {
	uint8 joyX;
	uint8 joyY;
	uint16 accelX;
	uint16 accelY;
	uint16 accelZ;
	uint8 buttonZ;
	uint8 buttonC;
} NunchukData_t;

void nunchukInit(void);
int nunchukReadData(void);
NunchukData_t nunchukGetData(void);
void nunchukPrintData(void);</pre>
<p>Yeah, so if you were to use my code, you&#8217;d see a C struct for the data output and four self-explanatory functions. Clean and simple.</p>
<p>However, my implementation in the source file (attached) is way shakier, involving GCC attributes, bitfields, and anonymous union-nested anonymous structs. But hey, that&#8217;s how I roll when I want to decode binary data. First I define this&#8230; <em>thing</em>:</p>
<pre class="brush: cpp; light: true; title: ; notranslate">typedef struct __attribute__((__packed__)) {
	union {
		struct {
			uint8 joyX;
			uint8 joyY;
			uint8 accelX_HI;
			uint8 accelY_HI;
			uint8 accelZ_HI;
			uint8 buttonZ   : 1;
			uint8 buttonC   : 1;
			uint8 accelX_LO : 2;
			uint8 accelY_LO : 2;
			uint8 accelZ_LO : 2;
		};

		uint8 buffer[6];
	};
} NunchukRegisters_t;</pre>
<p>What is that supposed to achieve? Well, it&#8217;s basically a 6-byte long C struct which corresponds to the bit patterns read off of the Nunchuk. Based on <a href="http://www.windmeadow.com/node/42">reading materials</a>, I know that the data is encoded/ciphered by the byte, and all the decoded data is swizzled together to save bandwidth.</p>
<p>Thus, I have a <a href="http://en.wikipedia.org/wiki/Union_(computer_science)">union</a> between the aforementioned struct and a size 6 byte array so I can fill up and decode the struct in a per-byte fashion, just by looping over the unioned array. The <code>__attribute__((__packed__))</code> is just an futile, unnecessary hint to my compiler to make sure it doesn&#8217;t pad out my struct with extraneous bytes.</p>
<p>How do I use this struct? Now this is the beautiful part:</p>
<pre class="brush: cpp; light: true; title: ; notranslate">int nunchukReadData(void) {
	NunchukRegisters_t nunchukRegs; // allocate space
	readNI2C1(NUNCHUK_ADDR, nunchukRegs.buffer, 6); // read from nunchuk

	int i;
	for(i = 0; i &lt; 6 ; i++) { // decode by byte
		nunchukRegs.buffer[i] = nunchukByteDecode(nunchukRegs.buffer[i]);
	}
	// assemble raw data
	nunchukData.joyX = nunchukRegs.joyX;
	nunchukData.joyY = nunchukRegs.joyY;
	nunchukData.accelX = (nunchukRegs.accelX_HI &lt;&lt; 2) | nunchukRegs.accelX_LO;
	nunchukData.accelY = (nunchukRegs.accelY_HI &lt;&lt; 2) | nunchukRegs.accelY_LO;
	nunchukData.accelZ = (nunchukRegs.accelZ_HI &lt;&lt; 2) | nunchukRegs.accelZ_LO;
	nunchukData.buttonZ = !nunchukRegs.buttonZ;
	nunchukData.buttonC = !nunchukRegs.buttonC;

	DELAY_US(50); // comm delay so nunchuk doesn't complain
	nunchukRequestData(); // signal nunchuk to read sensors again
	return 1;
}</pre>
<p>Notice how the unioning lets me fill up the registers without janky casting, and the bitfields in the nested anonymous prevents me from having to shift or mask off bits in order to decode the Nunchuk registers into my output data struct. For <a href="http://www.atom.com/funny_videos/haha_america/">comparative delta</a>, this is how the &#8220;<a href="http://todbot.com/arduino/sketches/WiichuckDemo/nunchuck_funcs.h">reference implementation</a>&#8221; looks on the Arduino:</p>
<pre class="brush: cpp; light: true; title: ; notranslate">// from http://todbot.com/arduino/sketches/WiichuckDemo/nunchuck_funcs.h
int joy_x_axis = nunchuck_buf[0];
int joy_y_axis = nunchuck_buf[1];
int accel_x_axis = nunchuck_buf[2]; // * 2 * 2;
int accel_y_axis = nunchuck_buf[3]; // * 2 * 2;
int accel_z_axis = nunchuck_buf[4]; // * 2 * 2;

int z_button = 0;
int c_button = 0;

// byte nunchuck_buf[5] contains bits for z and c buttons
// it also contains the least significant bits for the accelerometer data
// so we have to check each bit of byte outbuf[5]
if((nunchuck_buf[5] &gt;&gt; 0) &amp; 1)
	z_button = 1;
if((nunchuck_buf[5] &gt;&gt; 1) &amp; 1)
	c_button = 1;

if((nunchuck_buf[5] &gt;&gt; 2) &amp; 1)
	accel_x_axis += 2;
if((nunchuck_buf[5] &gt;&gt; 3) &amp; 1)
	accel_x_axis += 1;

if((nunchuck_buf[5] &gt;&gt; 4) &amp; 1)
	accel_y_axis += 2;
if((nunchuck_buf[5] &gt;&gt; 5) &amp; 1)
	accel_y_axis += 1;

if((nunchuck_buf[5] &gt;&gt; 6) &amp; 1)
	accel_z_axis += 2;
if((nunchuck_buf[5] &gt;&gt; 7) &amp; 1)
	accel_z_axis += 1;</pre>
<p>Yeah&#8230; I&#8217;d rather have nested anonymous structs than line after line of nasty bit twiddling. Let&#8217;s ignore the fact that the above example is a snippet of application code, while my decoding was library code, making it instantly superior from a software engineering standpoint. That is, the programmer who uses my code can pick up and run with an interface which is decoupled from how bits are swizzled by the Nunchuk. But, the coder above would have to reference a couple of websites to write her own decoding routines before <code>printf</code>&#8216;ing the data, for example.</p>
<h2>Non-volatile storage</h2>
<p>If there&#8217;s one thing I&#8217;m unhappy about with my choice of microcontroller, it&#8217;s that it doesn&#8217;t have built-in data EEPROM. EEPROM is flash memory, which is non-volatile—its contents are retained even when powered off. Most decent PICs have, in addition to RAM and program memory flash (where all your code is stored), a piece of data EEPROM acting as a memory-mapped peripheral which you can use as if it were an external EEPROM chip over SPI or I²C. The dsPIC33 family does not have this<sup><a href="http://www.geekshavefeelings.com/posts/hardbord-interesting-bits#footnote_3_776" id="identifier_3_776" class="footnote-link footnote-identifier-link" title="Though dsPIC30 does, for some reason.">4</a></sup>.</p>
<p>But I still want my non-volatile storage, so I can store Nunchuk calibration data in the transmitter. How? We write it to the program flash. To make a long story short, this is a fairly complicated procedure which was achieved by using Microchip&#8217;s <a href="http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;nodeId=2680&amp;dDocName=en538000">Data EEPROM Emulation library</a>, which turns unused program flash space into software-addressable EEPROM blocks. It even spreads writes over different blocks of allocated program flash in order to reduce wear on the EEPROM cells.</p>
<p>Trouble was, this library had some fairly odd software engineering practices, like putting way too much internals in a public header. It also used a separate unit of assembly language routines so the library could use specific instructions for flash reads and writes, when they could have been done in inline assembly, or even better, compiler built-in functions. It&#8217;s not like your assembly is more portable when you put it in a separate file, Microchip. :\</p>
<p>My modifications and simplifications to the library are attached to this post.</p>
<h2>The protocol</h2>
<p>RC control is essentially packeted data; each piece of data you send is a full state of what motors/LEDs should be doing what, with no dependence on past or future data. Xbees provide you with a bidirectional stream (yes, I know it&#8217;s packets underneath) rather than a packet interface like <a href="http://www.sparkfun.com/commerce/categories.php?c=114">Nordic radios</a>. For those who grok teh nets, it&#8217;s more TCP and less UDP.</p>
<p>So, I hacked up a protocol that took advantage of both: use escape characters and base64 encoding to represent binary packets, and human-readable ASCII which is ignored by the receiver.</p>
<p>First I define a data structure. Starting to see a pattern?</p>
<pre class="brush: cpp; light: true; title: ; notranslate">typedef struct {
	union {
		struct {
			uint16 speed;
			uint8 reversed;
			uint8 brake;
		};
		uint8 buffer[4];
	};
} FluffyData_t;</pre>
<p><code>FluffyData_t</code><sup><a href="http://www.geekshavefeelings.com/posts/hardbord-interesting-bits#footnote_4_776" id="identifier_4_776" class="footnote-link footnote-identifier-link" title="H&Auml;RDB&Ouml;RD used to be called Fluffy, in case you&amp;#8217;re wondering about the name.">5</a></sup> is the information the receiver cares about: speed, direction, and whether to brake. This is put through a base64 encode<sup><a href="http://www.geekshavefeelings.com/posts/hardbord-interesting-bits#footnote_5_776" id="identifier_5_776" class="footnote-link footnote-identifier-link" title="Note the byte array union again, which is great for doing binary transforms like b64 encoding.">6</a></sup>, and surrounded with non-base64 escape characters, ^ and $, into a 10-byte ASCII string.</p>
<p>Now, everything outside of those escape chars can be easily parsed out on the receiving end. So, now we have easily-decoded binary data represented as ASCII so it doesn&#8217;t screw with our terminals, and we can stick &#8220;comments&#8221; into the stream so we can peek in and read debug output.</p>
<p>For example, this is what actually goes through my Xbees:</p>
<pre class="brush: plain; light: true; title: ; notranslate">(Accel) x: 664, y: 450, z: 612 (Joystick) x: 148, y: 196 (Button) z: 1, c: 0
(fluffy) speed: 46260, reversed: 0, brake: 0
^tLQAAA==$
(Accel) x: 664, y: 450, z: 614 (Joystick) x: 148, y: 197 (Button) z: 1, c: 0
(fluffy) speed: 47031, reversed: 0, brake: 0
^t7cAAA==$</pre>
<p>That&#8217;s right, most of it is human readable. Only a tiny fraction of it is for the machine. This is called taking advantage of the bandwidth.</p>
<p>On the receiver end, it&#8217;s trivial to listen for a ^ character, start decoding base64 into another FluffyData_t struct, and then stop decoding upon receiving a $ character. Of course I am oversimplifying data integrity issues here, which are remedied in my design with a few simple checks and CRC16 checksums.</p>
<h2>Code listings</h2>
<ul>
<li><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/nunchuk.c">nunchuk.c</a></li>
<li><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/nunchuk.h">nunchuk.h</a></li>
<li><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/DEE-Emulation-16-bit.c">DEE Emulation 16-bit.c</a></li>
<li><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/DEE-Emulation-16-bit.h">DEE Emulation 16-bit.h</a></li>
</ul>
<p>Note that I use the excellent <a href="http://www.reesemicro.com/Home/pic24-software-library-collection">Reese/Jones/Bruce library for PIC24 &amp; dsPIC33</a> as my hardware interface library, which is referenced in the nunchuk.c code for I²C routines.</p>
<ol class="footnotes"><li id="footnote_0_776" class="footnote">With pin headers, Montresor! Sparkfun sells <em>only</em> headers at the same cost.</li><li id="footnote_1_776" class="footnote">Really a USB to serial adapter + LDO regulator with an Xbee footprint.</li><li id="footnote_2_776" class="footnote">OK, they are. But still. <em>SUPPLIES!</em></li><li id="footnote_3_776" class="footnote">Though dsPIC30 does, for some reason.</li><li id="footnote_4_776" class="footnote">HÄRDBÖRD used to be called Fluffy, in case you&#8217;re wondering about the name.</li><li id="footnote_5_776" class="footnote">Note the byte array union again, which is great for doing binary transforms like b64 encoding.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/hardbord-interesting-bits/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
<enclosure url="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/controllertest_720p.mp4" length="8562953" type="video/mp4" />
		</item>
		<item>
		<title>HÄRDBÖRD: Hardcore Electric Longboard</title>
		<link>http://www.geekshavefeelings.com/posts/hardbord-hardcore-electric-longboard</link>
		<comments>http://www.geekshavefeelings.com/posts/hardbord-hardcore-electric-longboard#comments</comments>
		<pubDate>Mon, 18 Oct 2010 04:06:22 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[comp.sci]]></category>
		<category><![CDATA[elec.engr]]></category>
		<category><![CDATA[hardbord]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=745</guid>
		<description><![CDATA[So I&#8217;m going to start using my blog as a build log for projects. All the cool kids are doing it. Introducing HÄRDBÖRD, the new reason for my keyboard layout Today, I want to turn your attention to HÄRDBÖRD1, this wireless, all-aluminum electric longboard/deathtrap project I got myself involved in. My roommate Jamison and I [...]]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;m going to start using my blog as a build log for projects. All the <a href="http://www.etotheipiplusone.net/">cool</a> <a href="http://thevariableconstant.blogspot.com/">kids</a> are doing it.</p>
<h2>Introducing HÄRDBÖRD, the new reason for my keyboard layout</h2>
<p>Today, I want to turn your attention to HÄRDBÖRD<sup><a href="http://www.geekshavefeelings.com/posts/hardbord-hardcore-electric-longboard#footnote_0_745" id="identifier_0_745" class="footnote-link footnote-identifier-link" title="Credit goes to Charles for this awesome name. Note that the Umlauts are metal umlauts, not actual German.">1</a></sup>, this wireless, all-aluminum electric longboard/deathtrap project I got myself involved in. My roommate <a href="http://thevariableconstant.blogspot.com/">Jamison</a> and I are the principal designers (engineers? build slaves?) on a pair of these for fun and&#8230; leverage against The Man? The idea here is to get some learning done, but we do end up with ridiculously cool looking, possibly overpowered boards to ride around campus on:</p>
<div id="attachment_746" class="wp-caption aligncenter" style="width: 490px"><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0507.jpg"><img class="size-large wp-image-746" title="HÄRDBÖRD (Unpowered)" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0507-480x640.jpg" alt="" width="480" height="640" /></a><p class="wp-caption-text">Take that, campus shuttle!</p></div>
<p>I&#8217;m mostly in charge of the electronics, which are pretty simple compared to the all the other stuff. Most of it was done in about a week<sup><a href="http://www.geekshavefeelings.com/posts/hardbord-hardcore-electric-longboard#footnote_1_745" id="identifier_1_745" class="footnote-link footnote-identifier-link" title="Much of that time was spent coding with my shirt off while Rammstein blasted from my workstation.">2</a></sup>. The plan is to use a Wii Nunchuk to wirelessly control the motor controllers. Why a Nunchuk? Why wireless? These transcendental questions of painful gravity are endless, but I can not answer them.</p>
<p>Jamison has done much of the mechanical design and machining, though I&#8217;ve been able to contribute a bit in the shop by learning the trade (i.e. the OMAX waterjet cutter in the Invention Studio at Georgia Tech). The boards are almost all waterjet-cut 6061 aluminum, with custom trucks, wheel hangers, deck—the whole shebang.  We&#8217;ve run into a few snags where the wheel hangers don&#8217;t center with as much force as we&#8217;d like (in fact, not enough to be rideable); I have an elegant solution involving one spring and a cam, but it&#8217;s unmachineable and apparently patented or licensed by <a href="http://www.originalskateboards.com/longboard-trucks">Original</a>.    <a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0508.jpg"><img class="aligncenter size-large wp-image-747" title="Trucks and batteries" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0508-640x480.jpg" alt="" width="640" height="480" /></a></p>
<p>Power runs from <em>huge</em> 4000mAh 6S1P pack lithium-polymer batteries (22.2V nominal, 25.2V max). They&#8217;re really not that big, but I haven&#8217;t built large bots for a long while so their size still surprises me. This juice runs to a pair of Turnigy brushless motors mounted within 4-inch 30A durometer polymer-core wheels, though what goes in between the motors and the batteries is still up for debate with the bean counters—no motor control solution for the pair of the boards costs less than $300.</p>
<p>For more information on &#8220;getting the boards to move,&#8221; see <a href="http://thevariableconstant.blogspot.com/search/label/HardBord">Jamo&#8217;s posts on Härdbörd</a>.</p>
<p>Meanwhile, we&#8217;re thinking of using a pair of <a href="https://downloads.maxonmotor.com/Katalog_neu/eshop/Downloads/maxon_motor_control/1-Q-EC-Verstaerker/DEC_Module_50_5/380200/380200_Operating_Instruction_E.pdf">Maxon DEC 50/5 (PDF)</a> sensored brushless control modules. Now I&#8217;d personally prefer to build my own brushless controllers, but we really want to see this on the road. These take in a few digital signals and a 0–5V analog signal for speed. Unfortunately, everything electronic I covet and hold dear (including my low-MIPS microcontroller of choice, the Microchip dsPIC33FJ128GP802) use 3.3V, and I hate analog like that flat watered-down Sprite you get from really stingy restaurants in NYC&#8217;s Chinatown. No sir, no op-amps in my design; I&#8217;d rather drink diet.</p>
<h2>An aside on my choice of µC</h2>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/dsPIC-pinout.png"><img class="aligncenter size-medium wp-image-770" title="dsPIC pinout" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/dsPIC-pinout-300x140.png" alt="" width="300" height="140" /></a></p>
<p>The nice thing about the <a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en532298">dsPIC33FJ128GP802</a> is that it&#8217;s chock-full of every sort of peripheral, as described in its <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/70292D.pdf">386-page datasheet</a>. If you don&#8217;t have a software solution, <em>it has a hardware solution</em>. If you don&#8217;t have a hardware solution, <em>it has a hardware solution</em>. If you already have a solution, <em>IT HAS A HARDWARE SOLUTION</em>.</p>
<p>In my computer architecture class, the professor was talking about the DEC VAX having a POLYD instruction to evaluate polynomials and everyone laughed at the ridiculously complex ISA co-designed by two Stuy alums. Then I realized, &#8220;dang, the dsPIC has a polynomial evaluator for CRC calculations!&#8221; Hardware bloat is not fastest in Intel&#8217;s newest SIMD floating point SSE6.8d extension, but in these little 8- and 16-bit buggers by means of the memory-mapped peripheral.</p>
<p>I mean seriously, in addition to the usual timers, ADCs, I²C, SPI, U(S)ARTs, CAN, and other junk, it&#8217;s got freaking DMA and multi-priority interrupt system for all of those. Then they decide that wasn&#8217;t enough and crammed an extra ALU and barrel shifter in there with 40-bit accumulators and called it a DSP engine. But wait, there&#8217;s more! There&#8217;s more space on the die! Let&#8217;s shove a comparator and a real-time clock in there!  Now they had more hardware than they had pins, so what do they do? STICK MUXES AND TRISTATE DRIVERS EVERYWHERE. Yeah, that&#8217;s right, <em>almost every peripheral on this thing can be mapped to any pin</em>. This thing even solves your PCB layout issues because you can <em>reconfigure your pinout in software</em>.</p>
<p>Oh yeah, this thing also doesn&#8217;t need a crystal to run at its full 40MIPS, has a free official GCC compiler, and comes in 28-pin breadboadable through hole (as free samples!). Life doesn&#8217;t get more perfect.</p>
<h2>The receiver</h2>
<p>Aside aside, I wanted to output  0–5V analog from my dsPIC33F. Well, first thing I see is that it&#8217;s got this DAC peripheral. Everything is fine and dandy unti—AUGH IT OUTPUTS A DIFFERENTIAL SIGNAL. In other words, not only is it not 0–5V, it&#8217;s not even 0–3.3V. It&#8217;s some janky 0.8–2.8V (-ish. Don&#8217;t quote me.) swing for audio use. Darn, now I have to ghetto-hack a DAC from the PWM hardware.</p>
<p>Fortunately, this is extremely straightforward. The Output Compare module, as the &#8220;PWM&#8221; module is called in the dsPIC33F/PIC24H lines, is one of the most pleasant hardware peripherals I&#8217;ve ever used, on any computer, ever. Put it like this: <em>it&#8217;s easier than the software way</em>. You set up a timer with some prescaler values against system clock, as well as a period match register for when it should reset the timer counter to 0. That&#8217;s right: not only can you set the frequency of the timer tick, but also the period by which it resets. Awsm.</p>
<pre class="brush: cpp; title: ; notranslate">static inline void configTimer2(void) {
	T2CON = T2_OFF | T2_IDLE_CON | T2_GATE_OFF | T2_32BIT_MODE_OFF | T2_SOURCE_INT | T2_PS_1_1;
	PR2 = usToU16Ticks(PWM_PERIOD, getTimerPrescale(T2CONbits)) - 1;
	TMR2 = 0; //clear timer2 value
	_T2IF = 0;
	_T2IP = 1;
	_T2IE = 1; //enable the Timer2 interrupt
}</pre>
<p>Anyways, next you just set up the output compare module to use that timer.</p>
<pre class="brush: cpp; title: ; notranslate">static inline void configOutputCompare1(void) {
	T2CONbits.TON = 0; //disable Timer when configuring Output compare
	CONFIG_RB14_AS_DIG_OUTPUT();
	CONFIG_OC1_TO_RP(14); //map OC1 to RP14/RB14
	//assumes TIMER2 initialized before OC1 so PRE bits are set
	OC1RS = 0; //initially off
	//turn on the compare toggle mode using Timer2
	OC1CON = OC_TIMER2_SRC | //Timer2 source
			OC_PWM_FAULT_PIN_DISABLE; //PWM, no fault detection
}</pre>
<p>The way this work is basically described by this timing diagram:</p>
<p style="text-align: center;"><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/Output-Compare.png"><img class="size-medium wp-image-751 aligncenter" title="Output Compare" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/Output-Compare-300x243.png" alt="" width="300" height="243" /></a></p>
<p>When the timer counter is less than register <code>OC1RS</code>, the OC1 pin (reconfigured by software as described above, to RP14) is output high. Otherwise, it&#8217;s output low. The period of rollover is defined by the timer&#8217;s period register <code>PR2</code>. In other words, the duty cycle (and thus average voltage) is exactly<sup><a href="http://www.geekshavefeelings.com/posts/hardbord-hardcore-electric-longboard#footnote_2_745" id="identifier_2_745" class="footnote-link footnote-identifier-link" title="Actually, there&amp;#8217;s a fencepost error here I&amp;#8217;m glossing over, but which is covered by my code snippet.">3</a></sup> OC1RS/PR2.</p>
<p>Aside: you know why this would be useless on your ATMEGATRON9000KFLASH4BYTERAM AVRDUINO CAPPUCCINO2001 device? It&#8217;s 8-bit. All of these registers would be 8-bit, and you&#8217;d either have crappy 8-bit timers that can&#8217;t do straightforward PWM like this or some janky concatenated 2×8-bit monster with terrible latency and 40 pages in errata. End aside.</p>
<p>OK, so now we know how the PWM works. But how do we get 5V output? Surely we&#8217;ll need an op amp to up our range to fiv—CATSLAP. <em>We don&#8217;t like your kind here.</em></p>
<p>Yeah, so there&#8217;s a dsPIC peripheral solution here. The digital pins on the dsPIC have an open-drain operation mode<sup><a href="http://www.geekshavefeelings.com/posts/hardbord-hardcore-electric-longboard#footnote_3_745" id="identifier_3_745" class="footnote-link footnote-identifier-link" title="Well, all of the I/O pins on the equivalent PIC24H do, but you&amp;#8217;re not supposed to use the dsPIC analog pins in open-drain since they&amp;#8217;re not 5V tolerant. Yes, it does work, but this puts your app outside of spec.">4</a></sup>. A pin in open-drain output mode is hard pull to low (drain) when its port register bit is 0, and tristated (high-impedance, Z, floating) when its bit is 1. This means you can hook up 5V pull-up resistor to it, and get 5V output from a 3.3V device.</p>
<p>Now all I need to do is feed that 5V signal to a RC filter tuned to attenuate the PWM frequency, and I&#8217;ll have a clean 5V DAC output. I feel like freaking 诸葛亮 right here.</p>
<h2>The test</h2>
<p>I&#8217;m working on all of this in the Invention Studio because I want an oscilloscope for this. Now the Invention Studio is an Mechanical Engineering shop, so the o-scope is a bit dinky, but hey, it&#8217;s digital, there are working probes around, and it works&#8230; for the most part.</p>
<div id="attachment_754" class="wp-caption aligncenter" style="width: 490px"><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0486.jpg"><img class="size-large wp-image-754" title="Oscope warning" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0486-480x640.jpg" alt="" width="480" height="640" /></a><p class="wp-caption-text">&quot;Try a USB flash drive which has a smaller memory size.&quot; OK, what?</p></div>
<p>Anyways, I don&#8217;t have real o-scope captures, so bear with my cellphone camera photos of the various test cases. So here&#8217;s the circuit under test:</p>
<div id="attachment_755" class="wp-caption aligncenter" style="width: 490px"><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0487.jpg"><img class="size-large wp-image-755 " title="Circuit under test" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0487-480x640.jpg" alt="" width="480" height="640" /></a><p class="wp-caption-text">The transmitter and receiver ghettoed up to a power supply and scope</p></div>
<p>Now let&#8217;s get some data:</p>
<div id="attachment_757" class="wp-caption aligncenter" style="width: 490px"><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0498.jpg"><img class="size-large wp-image-757" title="PWM DAC 2.47V" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0498-480x640.jpg" alt="" width="480" height="640" /></a><p class="wp-caption-text">This is the PWM output from the dsPIC, without open-drain</p></div>
<p>Being able to adjust the duty cycle of the waveform with a joystick is some hot stuff, especially if you fiddle with the trigger settings a bit. Now let&#8217;s hook up a 100KOhm×0.1µF RC filter on that. This has a cutoff frequency of about 16Hz, at which point half the signal is attenuated. Higher frequency signals are attenuated at 20dB per decade, so the 3.28kHz PWM frequency is attenuated by at least 40dB. Good enough for me to play Etch-A-Sketch on the scope with my Nunchuk:</p>
<div id="attachment_758" class="wp-caption aligncenter" style="width: 490px"><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0502.jpg"><img class="size-large wp-image-758" title="ETCH A SKETCH" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0502-480x640.jpg" alt="" width="480" height="640" /></a><p class="wp-caption-text">With RC filter and slooow sweep scope samples</p></div>
<p>And just for the hell of it, I measured the ripple of the analog:</p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0506.jpg"><img class="aligncenter size-large wp-image-760" title="IMG_0506" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/10/IMG_0506-480x640.jpg" alt="" width="480" height="640" /></a></p>
<p>About 30mV. Not bad. Taking this measurement was a real pain: I had to keep my joystick finger steady while zooming/panning on a tiny sliver of the vertical scale, throw in measurements, and praying that a little twitch won&#8217;t throw the waveform off the triggering level.</p>
<p>So, that concludes this really boring part of &#8220;reducing part count of everything to just a dsPIC.&#8221; Next time, I&#8217;ll show how I did this with the transmitter side.</p>
<ol class="footnotes"><li id="footnote_0_745" class="footnote">Credit goes to <a href="http://www.etotheipiplusone.net/">Charles</a> for this awesome name. Note that the Umlauts are metal umlauts, not actual German.</li><li id="footnote_1_745" class="footnote">Much of that time was spent coding with my shirt off while Rammstein blasted from my workstation.</li><li id="footnote_2_745" class="footnote">Actually, there&#8217;s a fencepost error here I&#8217;m glossing over, but which is covered by my code snippet.</li><li id="footnote_3_745" class="footnote">Well, all of the I/O pins on the equivalent PIC24H do, but you&#8217;re not supposed to use the dsPIC analog pins in open-drain since they&#8217;re not 5V tolerant. Yes, it does work, but this puts your app outside of spec.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/hardbord-hardcore-electric-longboard/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Path of the Wastrel</title>
		<link>http://www.geekshavefeelings.com/posts/path-of-the-wastrel</link>
		<comments>http://www.geekshavefeelings.com/posts/path-of-the-wastrel#comments</comments>
		<pubDate>Sun, 15 Aug 2010 02:15:50 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[gatech]]></category>
		<category><![CDATA[job]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=764</guid>
		<description><![CDATA[So I decided to follow up on my infamous &#8220;Oh the humanities&#8221; letter to my academic advisor: Hi again, It&#8217;s Xo once again, the ever-adoring fan of the academic advisement office at the Department of Electrical and Computer Engineering. I&#8217;d just like to update you on my summer as it has been so far since [...]]]></description>
			<content:encoded><![CDATA[<p>So I decided to follow up on my <a href="http://www.geekshavefeelings.com/posts/i-am-now-a-management-major">infamous &#8220;Oh the humanities&#8221; letter</a> to my academic advisor:</p>
<blockquote><p>Hi again,</p>
<p>It&#8217;s Xo once again, the ever-adoring fan of the academic advisement office at the Department of Electrical and Computer Engineering. I&#8217;d just like to update you on my summer as it has been so far since I received your <em>fantastic insight</em> into the <em>only</em> pedagogical path appropriate to me at this point in my life.</p>
<p>So far, I have taken the path of the wastrel. These past months have seen me experiment with various illegal substances and participate in violent (though hardly consequential, in my humble opinion) street crime, all while I gamble away my personal assets.</p>
<p>In anticipation of my next year of valuable instruction, especially in the humanities (oh them!), I&#8217;ve taken on cutting my body as an extracurricular. I find that it is an extremely intense form of expression. Cutting enthusiasts have advised me that I am a &#8220;natural&#8221; and that I should enter the pros—perhaps eventually compete in the World Championships.</p>
<p>I have shrugged off warnings from friends and family about my declining state of health and squalorous living conditions. I see no reason in their concern. After all, they&#8217;re the ones who suggested that I should have a say in the choice of coursework at university and that I should be free to pursue my education at a level comfortable for me. Ha! They were demonstrated to be wrong by your highly logical and considerate counseling; who are they to now dissuade me from a path that will lead to assured ruin among the outcasts of society?</p>
<p>Yours,<br />
Xo Wang</p></blockquote>
<p>Alright, so I haven&#8217;t actually been doing of the above mentioned, but instead trying to hold a job. The Office of Professional Development, or rather the whole of Georgia Tech, has been exceptionally unhelpful towards that end.</p>
<p>Though they are often lauded for their great co-op &amp; internship programs, GT basically withholds opportunities from freshmen. Their website isn&#8217;t open to anyone below a certain number of credit-hours and the staff are just unhelpful. What, are you afraid your students might catch up to those at better schools? God forbid any of us should get a head start on this professional development thing.</p>
<p>I started a bit at a hedge fund, decided finance was not for me, and switched into a rewarding internship at Barnes &amp; Noble, thanks in great part to a wonderful friend and mentor. Developing applications is pretty nice.</p>
<p>As an aside, I highly recommend the sandwiches from Financier Patisserie and burgers from Jimbo&#8217;s, if you&#8217;re ever around that corner in Midtown East. They&#8217;re good stuff.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/path-of-the-wastrel/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
<!-- 0.9505sec -->
<!-- Dynamic page generated in 0.924 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-06 06:18:18 -->
<!-- Compression = gzip -->
