<?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>Limina.Log &#187; Programming</title>
	<atom:link href="http://log.liminastudio.com/category/programming/feed" rel="self" type="application/rss+xml" />
	<link>http://log.liminastudio.com</link>
	<description>Research &#38; Development at Limina.Studio</description>
	<lastBuildDate>Sun, 15 Jan 2012 21:25:34 +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>Getting Started Developing with the WiMM One</title>
		<link>http://log.liminastudio.com/programming/getting-started-developing-with-the-wimm-one</link>
		<comments>http://log.liminastudio.com/programming/getting-started-developing-with-the-wimm-one#comments</comments>
		<pubDate>Sat, 17 Dec 2011 00:23:34 +0000</pubDate>
		<dc:creator>Tedb0t</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[WiMM]]></category>

		<guid isPermaLink="false">http://log.liminastudio.com/?p=955</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/getting-started-developing-with-the-wimm-one' addthis:title='Getting Started Developing with the WiMM One '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>We just received a Developer Preview of the new WiMM One wearable touchscreen device, and dove into developing for it.  It runs Android so you have to get the Android SDK set up.  Here are our notes so far. Install Eclipse.  I had the &#8220;Galileo&#8221; version which I found out the hard way isn&#8217;t supported, [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/getting-started-developing-with-the-wimm-one' addthis:title='Getting Started Developing with the WiMM One '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><div>We just received a Developer Preview of the new <a href="wimm.com">WiMM One</a> wearable touchscreen device, and dove into developing for it.  It runs Android so you have to get the Android SDK set up.  Here are our notes so far.</div>
<ol>
<li>Install Eclipse.  I had the &#8220;Galileo&#8221; version which I found out the hard way isn&#8217;t supported, so I downloaded the newest as of writing (&#8220;Indigo&#8221;).</li>
<li>Install the <a href="http://developer.android.com/sdk/index.html">Android SDK</a>.</li>
<li>Install the <a href="http://developer.android.com/sdk/eclipse-adt.html#installing">Android Developer Tools (ADT) plugin</a> for Eclipse.</li>
<li>Download the <a href="https://dev.wimm.com/developer/resources/sdk">WiMM Android Add-On</a> (make a free developer account first to get it).</li>
<li>Put the WiMM Add-On folder in the add-ons folder in the Android SDK.</li>
<li>Run the Android SDK Manager from Eclipse &gt; Window.</li>
<li>Select and install Android 2.1 (API 7) and the Android SDK Platform Tools.</li>
<li>Make a WiMM Android Virtual Device with SD card 2 GiB and resolution 160&#215;160.</li>
<li>You can now make new projects that target the WiMM One Add-On.</li>
</ol>
<p><strong>Building and Running on the Emulator</strong></p>
<ol>
<li>Open a terminal at [your-android-sdk]/add-ons/addon_wimm_one_7/tools and run ./emu.</li>
<li>Wait for the emulator to boot up (it takes a minute).</li>
<li>Hit &#8220;Run&#8221; in Eclipse.</li>
<ol>
<li>If you get an expired certificate error, <a href="http://stackoverflow.com/questions/2194808/debug-certificate-expired-error-in-eclipse-android-plugins">look here</a>.</li>
</ol>
<li>If you&#8217;re prompted to choose a device, choose the emulator.</li>
</ol>
<p><strong>Building and Running on the Device</strong></p>
<ol>
<li>On your WiMM, go to Settings &gt; Advanced and turn on &#8220;Allow USB debugging&#8221;</li>
<li>Plug in your WiMM.</li>
<li>Open a terminal at addon_wimm_one_7/tools and run ./android update adb.</li>
<li>Go to addon_wimm_one_7/platform-tools and run ./adb kill-server and ./adb start-server.</li>
<li>Now run ./adb devices and you should see your hardware device listed as well as any running emulators.</li>
<li>Now when you run your app from Eclipse, you can choose your hardware device!</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://log.liminastudio.com/programming/getting-started-developing-with-the-wimm-one/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting started with the RN-XV WiFi Module &amp; Node.js</title>
		<link>http://log.liminastudio.com/programming/getting-started-with-the-rn-xv-wifi-module-node-js</link>
		<comments>http://log.liminastudio.com/programming/getting-started-with-the-rn-xv-wifi-module-node-js#comments</comments>
		<pubDate>Thu, 08 Dec 2011 04:08:54 +0000</pubDate>
		<dc:creator>Tedb0t</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Physical Computing]]></category>
		<category><![CDATA[Sockets]]></category>

		<guid isPermaLink="false">http://log.liminastudio.com/?p=951</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/getting-started-with-the-rn-xv-wifi-module-node-js' addthis:title='Getting started with the RN-XV WiFi Module &#38; Node.js '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>The RN-XV WiFi module is a nifty little WiFi module designed to fit the same pinout as an XBee, so it&#8217;s intended to be a drop-in replacement. Tonight I whipped up a little test of the module to get a joystick to talk to a Node.js server over WiFi.  I attached +3V power and ground [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/getting-started-with-the-rn-xv-wifi-module-node-js' addthis:title='Getting started with the RN-XV WiFi Module &amp; Node.js '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>The <a href="http://www.sparkfun.com/products/10822">RN-XV WiFi module</a> is a nifty little WiFi module designed to fit the same pinout as an XBee, so it&#8217;s intended to be a drop-in replacement.</p>
<p>Tonight I whipped up a little test of the module to get <a href="http://www.sparkfun.com/products/9032">a joystick</a> to talk to a <a href="http://nodejs.org/">Node.js</a> server over WiFi.  I attached +3V power and ground to the module (pins 1 and 10, respectively), pin 2 (TX) to Arduino digital pin 0 (RX), and pin 1 (RX) to Arduino digital pin 1 (TX).  That&#8217;s all the hardware setup you need.</p>
<p>I used <a href="https://github.com/jcrouchley/WiFly-Shield">this WiFly library</a> to handle the connection.  All it does is talk to the WiFly module over serial and send control commands, so the library abstracts that a bit.  Here&#8217;s the Arduino sketch I built:<span id="more-951"></span></p>
<pre>#include "WiFly.h"

#define PIN_VERT      0  // analog
#define PIN_HOR       1  // analog

#define PIN_PUSH      2
#define PIN_LED_RED   3
#define PIN_LED_GRN   4

int vert = 0;
int hor = 0;
bool push;

char* ssid = "yourNetwork";
char* pass = "yourPassword";

char* serverAddress = "yourServer";
int serverPort = 1337;

Client client(serverAddress, serverPort);

void setup(){
  pinMode(PIN_PUSH, INPUT);
  pinMode(PIN_LED_RED, OUTPUT);
  pinMode(PIN_LED_GRN, OUTPUT);

  digitalWrite(PIN_PUSH, HIGH);    // set pull-up resistor
  digitalWrite(PIN_LED_RED, LOW);  // start off
  digitalWrite(PIN_LED_GRN, LOW);

  Serial.begin(9600);
  WiFly.setUart(&amp;Serial);
  WiFly.begin();

  if (!WiFly.join(ssid, pass, true)) {
    digitalWrite(PIN_LED_RED, HIGH);
    while (1) {
      // Hang on failure.
    }
  }

  digitalWrite(PIN_LED_GRN, HIGH);

  if (client.connect()) {
    client.println("ohai!");
    client.println();
  } else {
    // do nothing
  }
}

void loop(){
  vert = analogRead(PIN_VERT);
  hor = analogRead(PIN_HOR);
  push = digitalRead(PIN_PUSH);

  digitalWrite(PIN_LED_RED, !push);

  client.print(vert);
  client.print('\t');
  client.print(hor);
  client.print('\t');
  client.print(push);
  client.println();
  delay(10);
}</pre>
<p>And here&#8217;s the very basic Node.js server that just prints out the values it receives:</p>
<pre>var net = require('net');

var server = net.createServer(function(socket) { //'connection' listener
	console.log('server connected');

	socket.setEncoding('ascii');

	socket.on('end', function() {
		console.log('server disconnected');
	});

	socket.on('data', function(data){
		console.log(data);
	});
});

server.listen(1337, function() { //'listening' listener
	console.log('server bound');
});</pre>
]]></content:encoded>
			<wfw:commentRss>http://log.liminastudio.com/programming/getting-started-with-the-rn-xv-wifi-module-node-js/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>PQLabs Multitouch Screen Not Working in Windows 7? Enable It</title>
		<link>http://log.liminastudio.com/programming/pqlabs-multitouch-screen-not-working-in-windows-7-enable-it</link>
		<comments>http://log.liminastudio.com/programming/pqlabs-multitouch-screen-not-working-in-windows-7-enable-it#comments</comments>
		<pubDate>Mon, 21 Nov 2011 16:02:02 +0000</pubDate>
		<dc:creator>Tedb0t</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Multitouch]]></category>
		<category><![CDATA[Solution]]></category>
		<category><![CDATA[Touchscreen]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://log.liminastudio.com/?p=945</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/pqlabs-multitouch-screen-not-working-in-windows-7-enable-it' addthis:title='PQLabs Multitouch Screen Not Working in Windows 7? Enable It '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>I just discovered that, in order to get a PQLabs Multitouch screen in Windows 7 to properly report multitouch events (to Adobe AIR/Flash, in my case), one must go to Settings &#62; Pen and Touch, go to the Touch tab, and check &#8220;Enable multi-touch gestures and inking.&#8221;  Thanks, Windows. &#62;:-&#124;]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/pqlabs-multitouch-screen-not-working-in-windows-7-enable-it' addthis:title='PQLabs Multitouch Screen Not Working in Windows 7? Enable It '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>I just discovered that, in order to get a PQLabs Multitouch screen in Windows 7 to properly report multitouch events (to Adobe AIR/Flash, in my case), one must go to Settings &gt; Pen and Touch, go to the Touch tab, and check &#8220;Enable multi-touch gestures and inking.&#8221;  Thanks, Windows. &gt;:-|</p>
]]></content:encoded>
			<wfw:commentRss>http://log.liminastudio.com/programming/pqlabs-multitouch-screen-not-working-in-windows-7-enable-it/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Controlling Deluge Auto-Management and File Priorities via Python</title>
		<link>http://log.liminastudio.com/programming/controlling-deluge-auto-management-and-file-priorities-via-python</link>
		<comments>http://log.liminastudio.com/programming/controlling-deluge-auto-management-and-file-priorities-via-python#comments</comments>
		<pubDate>Tue, 15 Nov 2011 21:27:58 +0000</pubDate>
		<dc:creator>Tedb0t</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[BitTorrent]]></category>
		<category><![CDATA[Deluge]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://log.liminastudio.com/?p=943</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/controlling-deluge-auto-management-and-file-priorities-via-python' addthis:title='Controlling Deluge Auto-Management and File Priorities via Python '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Today I was working away from my home file server which runs the BitTorrent server Deluge.  My Deluge Web UI stopped working for some reason (and it never worked that well in the first place) and I really needed to start a torrent at home.  Deluge has an &#8220;Auto Managed&#8221; feature that&#8217;s enabled by default, [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/controlling-deluge-auto-management-and-file-priorities-via-python' addthis:title='Controlling Deluge Auto-Management and File Priorities via Python '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Today I was working away from my home file server which runs the BitTorrent server Deluge.  My Deluge Web UI stopped working for some reason (and it never worked that well in the first place) and I really needed to start a torrent at home.  Deluge has an &#8220;Auto Managed&#8221; feature that&#8217;s enabled by default, but since I seed a lot of torrents, it actually prevents a new torrent from starting to download automatically, so I have to disable that and the resume the torrent after adding it.  Thankfully Deluge has a Python client interface we can use to write our own scripts.</p>
<p>Here&#8217;s an example script that adds a URL from an argument with auto_managed turned off:</p>
<pre>#!/usr/bin/env python
# encoding: utf-8
"""
DelugeEasyAdd

Starts a new Deluge torrent from a URL.

Created by Ted Hayes.

"""

import urllib, os, sys, re
# Import the client module
from deluge.ui.client import client
# Import the reactor module from Twisted - this is for our mainloop
from twisted.internet import reactor

# Set up the logger to print out errors
from deluge.log import setupLogger
setupLogger()

# Connect to a daemon running on the localhost
# We get a Deferred object from this method and we use this to know if and when
# the connection succeeded or failed.
d = client.connect()

PRIO_NORMAL = 1
PRIO_MAX = 5

torrentURL = sys.argv[1]
# btjunkie URLs use 'download.torrent' as the filename, get a better one
if re.search("btjunkie", torrentURL):
    filename = re.findall("torrent\/(.*?)\/", torrentURL)[0]
else:
    filename = os.path.basename(torrentURL)

print "Using filename: %s" % filename

def addTorrent():
    client.core.add_torrent_url(torrentURL, '/home/daleth/Downloads/'+filename, {'auto_managed':False}).addCallback(added)

def added(s):
    print "Added status: ",s
    #client.core.resume_torrent()
    disconnect()

# We create a callback function to be called upon a successful connection
def on_connect_success(result):
    print "Connection was successful!"
    addTorrent()

def disconnect():
    print "disconnecting"
    client.disconnect()
    reactor.stop()

# We add the callback to the Deferred object we got from connect()
d.addCallback(on_connect_success)

# We create another callback function to be called when an error is encountered
def on_connect_fail(result):
    print "Connection failed!"
    print "result:", result

# We add the callback (in this case it's an errback, for error)
d.addErrback(on_connect_fail)

# Run the twisted main loop to make everything go
reactor.run()</pre>
<p>I still have to figure out how to then automatically resume the torrent.</p>
<p>Here are some helpful links:</p>
<p><a href="http://dev.deluge-torrent.org/wiki/Development/UiClient">UIClient Documentation<br />
</a></p>
<p><a href="http://dev.deluge-torrent.org/wiki/Development/1.3/UIClient">UIClient Example </a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://log.liminastudio.com/programming/controlling-deluge-auto-management-and-file-priorities-via-python/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arduino Serial.print sends numbers instead of letters</title>
		<link>http://log.liminastudio.com/itp/physical-computing/arduino-serial-print-sends-numbers-instead-of-letters</link>
		<comments>http://log.liminastudio.com/itp/physical-computing/arduino-serial-print-sends-numbers-instead-of-letters#comments</comments>
		<pubDate>Wed, 12 Oct 2011 03:04:49 +0000</pubDate>
		<dc:creator>Tedb0t</dc:creator>
				<category><![CDATA[Physical Computing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://log.liminastudio.com/?p=934</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/itp/physical-computing/arduino-serial-print-sends-numbers-instead-of-letters' addthis:title='Arduino Serial.print sends numbers instead of letters '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Recently I experienced a somewhat baffling, unexpected problem. I was using a line like: Serial.println('test'); And getting a series of numbers like 25536 instead of the expected text. It turned out the problem was just the use of the &#8216; instead of a &#8220;. Sigh.]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/itp/physical-computing/arduino-serial-print-sends-numbers-instead-of-letters' addthis:title='Arduino Serial.print sends numbers instead of letters '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Recently I experienced a somewhat baffling, unexpected problem. I was using a line like:</p>
<pre>Serial.println('test');</pre>
<p>And getting a series of numbers like 25536 instead of the expected text.  It turned out the problem was just the use of the &#8216; instead of a &#8220;.  Sigh.</p>
]]></content:encoded>
			<wfw:commentRss>http://log.liminastudio.com/itp/physical-computing/arduino-serial-print-sends-numbers-instead-of-letters/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>AVRdude Verification Error Solution</title>
		<link>http://log.liminastudio.com/itp/physical-computing/avrdude-verification-error-solution</link>
		<comments>http://log.liminastudio.com/itp/physical-computing/avrdude-verification-error-solution#comments</comments>
		<pubDate>Wed, 12 Oct 2011 02:22:48 +0000</pubDate>
		<dc:creator>Tedb0t</dc:creator>
				<category><![CDATA[Physical Computing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[avrdude]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://log.liminastudio.com/?p=931</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/itp/physical-computing/avrdude-verification-error-solution' addthis:title='AVRdude Verification Error Solution '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>If you&#8217;ve been getting an Arduino error like this: avrdude: verifying ... avrdude: verification error, first mismatch at byte 0x0007 0xff != 0x7f avrdude: verification error; content mismatch It may be as simple a fix as moving your USB cable from a hub directly to your computer—that fixed it for me! More information: I had [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/itp/physical-computing/avrdude-verification-error-solution' addthis:title='AVRdude Verification Error Solution '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>If you&#8217;ve been getting an Arduino error like this:</p>
<pre>avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0007
         0xff != 0x7f
avrdude: verification error; content mismatch</pre>
<p>It may be as simple a fix as moving your USB cable from a hub directly to your computer—that fixed it for me!</p>
<p>More information: I had also been getting errors like this from avrdude:</p>
<pre>avrdude: 2 retries during SPI command</pre>
]]></content:encoded>
			<wfw:commentRss>http://log.liminastudio.com/itp/physical-computing/avrdude-verification-error-solution/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bash snippet: Remove text from filenames</title>
		<link>http://log.liminastudio.com/programming/bash-snippet-remove-text-from-filenames</link>
		<comments>http://log.liminastudio.com/programming/bash-snippet-remove-text-from-filenames#comments</comments>
		<pubDate>Fri, 26 Aug 2011 23:58:10 +0000</pubDate>
		<dc:creator>Tedb0t</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[filenames]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[snippet]]></category>

		<guid isPermaLink="false">http://log.liminastudio.com/?p=919</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/bash-snippet-remove-text-from-filenames' addthis:title='Bash snippet: Remove text from filenames '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Today I had a directory full of mp3 files for a Flash game that each had the text &#8220;woman01&#8243; in them.  Since I wanted to just keep the rest of the filename, I put together this Bash one-liner: for f in *; do mv $f ${f/woman01/}; done Simple and effective!  Bash has a surprising array [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/bash-snippet-remove-text-from-filenames' addthis:title='Bash snippet: Remove text from filenames '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Today I had a directory full of mp3 files for a Flash game that each had the text &#8220;woman01&#8243; in them.  Since I wanted to just keep the rest of the filename, I put together this Bash one-liner:</p>
<pre>for f in *; do mv $f ${f/woman01/}; done</pre>
<p>Simple and effective!  Bash has a surprising array of string-manipulation capabilities, which I learned about <a href="http://tldp.org/LDP/abs/html/string-manipulation.html">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://log.liminastudio.com/programming/bash-snippet-remove-text-from-filenames/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programming an ATMega With No Bootloader Using the USBtinyISP</title>
		<link>http://log.liminastudio.com/itp/physical-computing/programming-an-atmega-with-no-bootloader-using-the-usbtinyisp</link>
		<comments>http://log.liminastudio.com/itp/physical-computing/programming-an-atmega-with-no-bootloader-using-the-usbtinyisp#comments</comments>
		<pubDate>Mon, 15 Aug 2011 03:38:09 +0000</pubDate>
		<dc:creator>Tedb0t</dc:creator>
				<category><![CDATA[Physical Computing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[ATMega]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[avrdude]]></category>

		<guid isPermaLink="false">http://log.liminastudio.com/?p=914</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/itp/physical-computing/programming-an-atmega-with-no-bootloader-using-the-usbtinyisp' addthis:title='Programming an ATMega With No Bootloader Using the USBtinyISP '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>The title says it all: for my &#8220;Deconspectrum&#8221; installation, I am burning a program onto a bunch of ATMega328 chips using a USBtinyISP (In-System Programmer).  At first I was running into a perplexing problem: the program was running much slower than it should have been.  I could tell immediately because I had a short POST [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/itp/physical-computing/programming-an-atmega-with-no-bootloader-using-the-usbtinyisp' addthis:title='Programming an ATMega With No Bootloader Using the USBtinyISP '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>The title says it all: for my <a href="http://log.liminastudio.com/projects/deconspectrum">&#8220;Deconspectrum&#8221; installation</a>, I am burning a program onto a bunch of ATMega328 chips using a USBtinyISP (In-System Programmer).  At first I was running into a perplexing problem: the program was running much slower than it should have been.  I could tell immediately because I had a short POST (Power-On Self Test) at the beginning of the program that flashes the LED Red-Green-Blue, and it was going far slower than it should have been.<span id="more-914"></span></p>
<p>My first thought was that there was a problem with the ATMega &#8220;fuses,&#8221; which are just settings for various esoteric details of the chip&#8217;s functioning, including clock rate.  But I had never had to bother with them before.  Then I made a further discovery that the only time the program ran correctly was if I installed the Arduino bootloader first and uploaded the program using it.  What gives?</p>
<p>Thanks to the plucky denizens of the ITP Physical Computing list, I learned that indeed, it was a matter of fuses—the Arduino IDE apparently only sets the correct fuses when burning the bootloader, not when burning a program directly using an ISP.</p>
<p>The solution: use avrdude, the program that Arduino uses to actually program the chip behind the scenes, directly.  This turned out to not only solve my problem, but to make the programming process much faster and simpler.  Avrdude takes a &#8220;hex&#8221; file as an input to transfer to the chip, which is the compiled bytecode that the ATMega actually runs.  This way, I only have to compile the program once, and burn it directly—and since I&#8217;m programming about 40 chips, this makes things far faster.</p>
<p>All you need to do is get the <a href="http://www.obdev.at/products/crosspack/index.html">AVR &#8220;CrossPack&#8221;</a> installed (for OSX; for Windows you can use AVR Studio or a number of other packages) and then find your hex file.  In the Arduino IDE, hold Shift while pressing the &#8220;Verify&#8221; button to produce a verbose debug output.  In there you&#8217;ll see a path like this:</p>
<pre>/var/folders/9t/7qf1680d2pqgd0hy6qbfkqsr0000gn/T/build5025172614724793636.tmp/myProgram.cpp.hex</pre>
<p>You can then copy that file to your project directory:</p>
<pre>cp /var/folders/.../myProgram.cpp.hex ~/Projects/myProject/myProgram.cpp.hex</pre>
<p>And program your chip like so:</p>
<pre>avrdude -c usbtiny -p m328p -b 57600 -U flash:w:myProgram.cpp.hex:i -U efuse:w:0x05:m -U hfuse:w:0xde:m -U lfuse:w:0xff:m</pre>
<p>Those settings are for the ATMega328; for the 168 use:</p>
<pre>-p m168</pre>
<p>To get a list of parts, type:</p>
<pre>avrdude -c avrisp</pre>
<p>And there you have it! You&#8217;ll find that this saves a lot of time if you have to program lots of chips. Besides, not using the Arduino bootloader will save a little space on your chip <img src='http://log.liminastudio.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://log.liminastudio.com/itp/physical-computing/programming-an-atmega-with-no-bootloader-using-the-usbtinyisp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arduino: Compensating for a Logarithmic Curve</title>
		<link>http://log.liminastudio.com/programming/arduino-compensating-for-a-logarithmic-curve</link>
		<comments>http://log.liminastudio.com/programming/arduino-compensating-for-a-logarithmic-curve#comments</comments>
		<pubDate>Thu, 04 Aug 2011 20:05:45 +0000</pubDate>
		<dc:creator>Tedb0t</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Logarithm]]></category>
		<category><![CDATA[Sound]]></category>

		<guid isPermaLink="false">http://log.liminastudio.com/?p=904</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/arduino-compensating-for-a-logarithmic-curve' addthis:title='Arduino: Compensating for a Logarithmic Curve '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Did you know that the scale of acoustic pitches is logarithmic?  This means that, even though we perceive the scale of notes as increasing or decreasing linearly, the actual frequencies are doubling or halving with each octave. In my Deconspectrum installation, I&#8217;m mapping acoustic frequencies to color.  If I mapped them linearly, the colors would [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/programming/arduino-compensating-for-a-logarithmic-curve' addthis:title='Arduino: Compensating for a Logarithmic Curve '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Did you know that the scale of acoustic pitches is logarithmic?  This means that, even though we perceive the scale of notes as increasing or decreasing linearly, the actual frequencies are doubling or halving with each octave.</p>
<p>In my <a href="http://log.liminastudio.com/projects/deconspectrum">Deconspectrum installation</a>, I&#8217;m mapping acoustic frequencies to color.  If I mapped them linearly, the colors would change very rapidly in the low frequencies, and then stop changing as obviously as the pitch gets higher.  This is not the effect you would expect, since you want each pitch to be represented by another color.</p>
<p>The solution is to map frequency to color (hue) logarithmically instead of linearly.  Thankfully, AVR C gives us a handy base-10 log function:</p>
<pre>int hueFreq = log10(frequency - FREQ_MIN) * hueScale;</pre>
<p>If we graph this, we get:</p>
<p><a href="http://log.liminastudio.com/wp-content/uploads/2011/08/Freq_Hue_Lin.png"  rel="lightbox[roadtrip]"><img class="alignleft size-medium wp-image-905" title="Freq_Hue_Lin" src="http://log.liminastudio.com/wp-content/uploads/2011/08/Freq_Hue_Lin-300x165.png" alt="" width="300" height="165" /></a>The &#8216;y&#8217; scale is hue and the &#8216;x&#8217; is frequency.  You can see that, with each octave, the change in color progresses more naturally, mimicking our linear perception of pitch.</p>
<p>Here&#8217;s the same graph with a logarithmic frequency axis:</p>
<p><a href="http://log.liminastudio.com/wp-content/uploads/2011/08/Freq_Hue_Log.png"  rel="lightbox[roadtrip]"><img class="alignleft size-medium wp-image-906" title="Freq_Hue_Log" src="http://log.liminastudio.com/wp-content/uploads/2011/08/Freq_Hue_Log-300x161.png" alt="" width="300" height="161" /></a>The dotted line is the log10 function without the cutoff, so you can see the &#8220;simulated&#8221; linearity.</p>
<p>Handy, and highly effective!</p>
]]></content:encoded>
			<wfw:commentRss>http://log.liminastudio.com/programming/arduino-compensating-for-a-logarithmic-curve/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arduino: Controlling an RGB LED by Hue</title>
		<link>http://log.liminastudio.com/itp/physical-computing/arduino-controlling-an-rgb-led-by-hue</link>
		<comments>http://log.liminastudio.com/itp/physical-computing/arduino-controlling-an-rgb-led-by-hue#comments</comments>
		<pubDate>Thu, 04 Aug 2011 19:54:08 +0000</pubDate>
		<dc:creator>Tedb0t</dc:creator>
				<category><![CDATA[Physical Computing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[RGB LED]]></category>

		<guid isPermaLink="false">http://log.liminastudio.com/?p=902</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/itp/physical-computing/arduino-controlling-an-rgb-led-by-hue' addthis:title='Arduino: Controlling an RGB LED by Hue '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Hooking up an RGB LED to an Arduino isn&#8217;t hard by itself, but controlling it can be—if you know what color you want to display, how do you know what R, G and B values that is? Here&#8217;s some Arduino code, adapted and simplified from Kasper Kamperman, that I am using in my Deconspectrum art [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://log.liminastudio.com/itp/physical-computing/arduino-controlling-an-rgb-led-by-hue' addthis:title='Arduino: Controlling an RGB LED by Hue '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Hooking up an RGB LED to an Arduino isn&#8217;t hard by itself, but controlling it can be—if you know what color you want to display, how do you know what R, G and B values that is?</p>
<p>Here&#8217;s some Arduino code, adapted and simplified from <a href="http://www.kasperkamperman.com/blog/arduino/arduino-programming-hsb-to-rgb/">Kasper Kamperman</a>, that I am using in my <a href="http://log.liminastudio.com/projects/deconspectrum">Deconspectrum art installation</a> to do just that:<span id="more-902"></span></p>
<pre>void setLED(int hue, int l){
	int col[3] = {0,0,0};
	getRGB(hue, 255, l, col);
	ledWrite(col[0], col[1], col[2]);
}

void getRGB(int hue, int sat, int val, int colors[3]) {
	// hue: 0-259, sat: 0-255, val (lightness): 0-255
	int r, g, b, base;

	if (sat == 0) { // Achromatic color (gray).
		colors[0]=val;
		colors[1]=val;
		colors[2]=val;
	} else  {
		base = ((255 - sat) * val)&gt;&gt;8;
		switch(hue/60) {
			case 0:
				r = val;
				g = (((val-base)*hue)/60)+base;
				b = base;
				break;
			case 1:
				r = (((val-base)*(60-(hue%60)))/60)+base;
				g = val;
				b = base;
				break;
			case 2:
				r = base;
				g = val;
				b = (((val-base)*(hue%60))/60)+base;
				break;
			case 3:
				r = base;
				g = (((val-base)*(60-(hue%60)))/60)+base;
				b = val;
				break;
			case 4:
				r = (((val-base)*(hue%60))/60)+base;
				g = base;
				b = val;
				break;
			case 5:
				r = val;
				g = base;
				b = (((val-base)*(60-(hue%60)))/60)+base;
				break;
		}
		colors[0]=r;
		colors[1]=g;
		colors[2]=b;
	}
}

void ledWrite(int r, int g, int b){
	analogWrite(LED_RED, 255-r);
	analogWrite(LED_GREEN, 255-g);
	analogWrite(LED_BLUE, 255-b);
}</pre>
<p>This gives you a very straightforward setLED function that takes a Hue from 0-359 and a Lightness from 0-255 (it could easily be adapted to specify the Saturation as well, which I have fixed at the maximum).</p>
<p>Note that the ledWrite function is designed for common-anode LEDs, where the microprocessor is current-sinking instead of sourcing; if you are current-sourcing, just take out the 255-val inversion.</p>
]]></content:encoded>
			<wfw:commentRss>http://log.liminastudio.com/itp/physical-computing/arduino-controlling-an-rgb-led-by-hue/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

