<?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>Project Lab</title>
	<atom:link href="http://nootropicdesign.com/projectlab/feed/" rel="self" type="application/rss+xml" />
	<link>http://nootropicdesign.com/projectlab</link>
	<description></description>
	<lastBuildDate>Wed, 14 Jul 2010 15:04:20 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Toolduino</title>
		<link>http://nootropicdesign.com/projectlab/2010/07/14/toolduino/</link>
		<comments>http://nootropicdesign.com/projectlab/2010/07/14/toolduino/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 12:21:02 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Processing]]></category>

		<guid isPermaLink="false">http://nootropicdesign.com/projectlab/?p=270</guid>
		<description><![CDATA[Toolduino is an open-source software tool that you use to test your Arduino circuits.  Toolduino communicates with your Arduino through a serial connection so that you can manipulate the pin outputs and read the inputs.  Go to the Toolduino page to download it and for all the details on how to use it!
]]></description>
			<content:encoded><![CDATA[<a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/07/toolduinoScreenshot.png"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/07/toolduinoScreenshot.png" alt="" title="toolduinoScreenshot" width="550" height="500" class="size-full wp-image-269" /></a>
<p><a href="/toolduino/">Toolduino</a> is an open-source software tool that you use to test your Arduino circuits.  Toolduino communicates with your Arduino through a serial connection so that you can manipulate the pin outputs and read the inputs.  Go to the <a href="/toolduino/">Toolduino page</a> to download it and for all the details on how to use it!</p>
]]></content:encoded>
			<wfw:commentRss>http://nootropicdesign.com/projectlab/2010/07/14/toolduino/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speed Trap!  A GPS-Based Speeding Alert</title>
		<link>http://nootropicdesign.com/projectlab/2010/04/05/speed-trap/</link>
		<comments>http://nootropicdesign.com/projectlab/2010/04/05/speed-trap/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 17:37:50 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Automotive]]></category>
		<category><![CDATA[GPS]]></category>
		<category><![CDATA[Level 9]]></category>

		<guid isPermaLink="false">http://nootropicdesign.com/projectlab/?p=184</guid>
		<description><![CDATA[Difficulty Level = 9  [What's this?]
This was a fun project I built using a perf-board Arduino with GPS receiver, some LEDs, some long wire, some clever code, and a car!  
I have this friend that has a speeding problem.  So I built this device for my friend so he&#8217;ll know when he&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Difficulty Level = 9</em></strong>  <a href="/projectlab/difficulty-levels/">[What's this?]</a></p>
<p>This was a fun project I built using a perf-board Arduino with GPS receiver, some LEDs, some long wire, some clever code, and a car!  </p>
<p>I have this <em>friend</em> that has a speeding problem.  So I built this device for my <em>friend</em> so he&#8217;ll know when he&#8217;s speeding.  How will he know?  Because when the small perf-board Arduino device with a GPS module detects that his vehicle&#8217;s speed is over the speed limit, it turns on a police lights display that is mounted on the inside of his car&#8217;s rear windshield.  When he sees those flashing police lights in the rear-view mirror, he&#8217;ll know he needs to slow down!</p>
<div id="attachment_189" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/speedTrap-rearview.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/speedTrap-rearview.jpg" alt="" title="speedTrap-rearview" width="640" height="480" class="size-full wp-image-189" /></a><p class="wp-caption-text">Police in the rear view mirror!</p></div>
<p>OK, it&#8217;s me, but you already figured that out.  If you weren&#8217;t smart, you wouldn&#8217;t be here.  Here&#8217;s a rundown of this project&#8217;s features:</p>
<ul>
<li>A simple perf-board Arduino circuit with an <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=465">EM-406a GPS Receiver</a> connected to the microcontroller</li>
<li>A pair of CAT-5 cables running from the circuit to the back of my Honda Civic</li>
<li>A small perf-board with red and blue LEDs and two white LEDs representing the headlights of a police car.  This small board is mounted on the inside of the rear windshield using suction cups.</li>
<li>The software running on the microcontroller is programmed to know the speed limit in different locations near where I live and drive.  I did this by specifying &#8220;speed zones&#8221; which are polygons and a speed limit.  The polygons are defined as a list of latitude/longitude vertices.</li>
<li>Whenever the GPS module reports the current position and speed (every second) the code determines which bounding polygon or &#8220;speed zone&#8221; the car is located in.  If the GPS receiver reports that the current speed is greater than the speed zone&#8217;s limit, the police lights are activated.  If below the speed limit, the lights will be turned off.
</ul>
<h3>The Hardware</h3>
<p>Look at this nice clean circuit&#8230;<br />
<a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/gpsArduino-top.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/gpsArduino-top.jpg" alt="" title="gpsArduino-top" width="640" height="480" class="alignnone size-full wp-image-181" /></a></p>
<p>OMG don&#8217;t look at the bottom!<br />
<a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/gpsArduino-bottom.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/gpsArduino-bottom.jpg" alt="" title="gpsArduino-bottom" width="640" height="480" class="alignnone size-full wp-image-180" /></a></p>
<p><span id="more-184"></span><br />
This is the schematic.  This is just a perf-board version of an Arduino with a few extra things.  Ten of the digital outputs are connected to a header for the cable to connect to.  The GPS receiver is connected to power and ground, and tied to the TX and RX pins on the ATMEGA328 microcontroller.  There is a test switch connected to Arduino pin 9 (ATMEGA328 pin 15).  Lastly, there&#8217;s a 5 pin header for interfacing with a USB to serial board so I can program the chip.  The 5 pins are 5V, GND, TX, RX, and the DTR signal for resetting the ATMEGA328 processor when the chip is programmed.<br />
<a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/speedTrapSchematic.png"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/speedTrapSchematic-sm.png" alt="" title="speedTrapSchematic-sm" width="640" height="375" class="alignnone size-full wp-image-199" /></a></p>
<p>Here&#8217;s the circuit board connected to the messy CAT-5 wiring harness.  There&#8217;s about 6 feet of wire running to the LED circuit board.<br />
<div id="attachment_182" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/speedTrap-connected.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/speedTrap-connected.jpg" alt="" title="speedTrap-connected" width="640" height="480" class="size-full wp-image-182" /></a><p class="wp-caption-text">The simple GPS Arduino conntected to a battery and the wires that run to the police lights.</p></div></p>
<p>The test button can be used to verify that everything is connected.<br />
<div id="attachment_183" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/speedTrap-lights.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/speedTrap-lights.jpg" alt="" title="speedTrap-lights" width="640" height="480" class="size-full wp-image-183" /></a><p class="wp-caption-text">Blinky police lights that mount on the rear windshield of my car.</p></div></p>
<p>Here&#8217;s how the LED circuit board looks mounted in the rear windshield.  I put a small square of black paper above the circuit board to reduce reflection on the glass.<br />
<div id="attachment_208" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/speedTrap-incar.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/speedTrap-incar.jpg" alt="" title="speedTrap-incar" width="640" height="480" class="size-full wp-image-208" /></a><p class="wp-caption-text">LED circuit board mounted on inside of rear windshield</p></div></p>
<p>This is what it looks like when the police lights are activated.  First a video shot to the rear of the car, then what it looks like in the rear view mirror.  It was difficult to capture this on video, and it really doesn&#8217;t do it justice.  I can tell you that when driving around at night, the illusion is fantastic.  It really does look like there is a police car behind you!<br />
<object width="640" height="480"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=10145670&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=10145670&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="480"></embed></object><br />
<h3>The Code</h3>
<p><a href="http://nootropicdesign.com/projectlab/downloads/SpeedTrap.pde">Download the full Arduino code here.</a></p>
<p>The software running on the Arduino ATMEGA328 chip utilizes the wonderfully robust <a href="http://arduiniana.org/libraries/NewSoftSerial/">NewSoftSerial</a> library for communicating with the EM-406a GPS module and the very convenient <a href="http://arduiniana.org/libraries/tinygps/">TinyGPS</a> library for parsing the NMEA sentences from the EM-406a.  Both of these awesome libraries are provided by Mikal Hart.</p>
<p>The TinyGPS library makes it easy to obtain the speed over ground in miles per hour.  The method for determining whether my car is speeding or not depends not only on knowing how fast I&#8217;m going and where I am, but also knowing what the speed limit is where I am.  For this, I have to hard-code in the information about various speed zones in the area I&#8217;m driving.  This isn&#8217;t as tedious as it sounds.  The idea is to define polygons on a map that represent different speed zones.  Here&#8217;s a map I sketched in order to plan my code.  I just did a screen capture in Google Maps and then drew on it with a simple drawing program.  Click through for a larger version:</p>
<div id="attachment_215" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/polygonsMap-large.png"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/polygonsMap-640x480.png" alt="Click for larger map" title="polygonsMap-640x480" width="640" height="480" class="size-full wp-image-215" /></a><p class="wp-caption-text">Map showing polygons definition for my neighborhood - click through for larger map</p></div>
<p>Then I used a simple tool provided at Google Maps called the <a href="http://code.google.com/apis/maps/documentation/examples/tile-detector.html">&#8220;tile detector&#8221;</a>.  By clicking on the tile detector map you can easily determine the latitude and longitude of any point.  Then I defined polygons in the setupSpeedZones().  Each zone has a speed limit and a list of vertices that define the polygon.</p>
<pre class="code">
  // Rockford Road
  speedZones[0] = &#038;SpeedZone(45);
  speedZones[0]->setVertices(6, (Vertex[6]){
      Vertex(45.027162772967756, -93.48137855529785),
      Vertex(45.02946790848425, -93.4742546081543),
      Vertex(45.02955889877115, -93.46193790435791),
      Vertex(45.02861865883124, -93.46172332763672),
      Vertex(45.02861865883124, -93.47412586212158),
      Vertex(45.02649547957147, -93.48133563995361)});

  // Schmidt Lake Rd
  speedZones[1] = &#038;SpeedZone(45);
  speedZones[1]->setVertices(10, (Vertex[10]){
      Vertex(45.044176126280206, -93.48219394683838),
      Vertex(45.04390322470628, -93.47322463989258),
      Vertex(45.043387740403595, -93.46974849700928),
      Vertex(45.0440548368525, -93.46498489379883),
      Vertex(45.0440548368525, -93.46185207366943),
      Vertex(45.04332709488612, -93.46185207366943),
      Vertex(45.0433574176529, -93.46580028533936),
      Vertex(45.04272063617576, -93.46983432769775),
      Vertex(45.043266449304376, -93.47434043884277),
      Vertex(45.04332709488612, -93.48215103149414)});

      ...
</pre>
<p>The function getSpeedLimit() checks to see if the current GPS position is within each speed zone starting with the first one.  Note that I defined a &#8220;catch all&#8221; speed zone with a limit of 25mph around the whole area.  It&#8217;s ok if polygons overlap as long as you understand that the first match found will be the one that is used for the speed limit.  This means you have to order your speed zone definitions with care.  My catch all speed zone is defined last for this reason.</p>
<p>The algorithm for determining if a point is within a polygon is actually quite simple (I was surprised).  I adapted my code from the <a href="http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html">algorithm provided here</a>.  I&#8217;m grateful that I found such a simple implementation to use.</p>
<p>The rest of the code should be pretty self-explanatory.  If the car is speeding, turn on the police lights.  If not, turn them off.  <a href="http://nootropicdesign.com/projectlab/downloads/SpeedTrap.pde">Download the full Arduino code here.</a></p>
<p><h3>Conclusions</h3>
<p>This project worked amazingly well.  The GPS receiver can take a long time (maybe 3 minutes) to get a fix when it is powered on, but once it gets a fix, it is very accurate.  The only shortcoming is that the EM-406a receiver only outputs NMEA sentences once per second, so there&#8217;s a bit of lag, but for the most part this device would correctly react to speed limit changes almost immediately after crossing a speed zone polygon border.</p>
<p>The speed over ground reported by the EM-406a is pretty accurate but seemed to be about 2mph lower than what my speedometer in my car reports.  So if I was in a 45mph speed zone, the police lights would not come on until I got up to about 47mph.  If this difference is consistent, I could easily compensate for it in the software.</p>
<p>Overall, this was a really fun project with great results!</p>
]]></content:encoded>
			<wfw:commentRss>http://nootropicdesign.com/projectlab/2010/04/05/speed-trap/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Tutorial: Reading a 12-Button Keypad</title>
		<link>http://nootropicdesign.com/projectlab/2010/04/03/keypad-tutorial/</link>
		<comments>http://nootropicdesign.com/projectlab/2010/04/03/keypad-tutorial/#comments</comments>
		<pubDate>Sat, 03 Apr 2010 18:29:54 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Level 1]]></category>

		<guid isPermaLink="false">http://nootropicdesign.com/projectlab/?p=250</guid>
		<description><![CDATA[Difficulty Level = 1  [What's this?]
Most keypads like this are wired so it makes it straightforward to figure out what button is being pressed.  With 3 columns and 4 rows of buttons, you only need 7 wires.  Typically all the buttons in a column are connected together with the same wire, and [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Difficulty Level = 1</em></strong>  <a href="/projectlab/difficulty-levels/">[What's this?]</a></p>
<p>Most keypads like this are wired so it makes it straightforward to figure out what button is being pressed.  With 3 columns and 4 rows of buttons, you only need 7 wires.  Typically all the buttons in a column are connected together with the same wire, and all the buttons in a row are connected together with the same wire.  To determine which button is pressed, you apply a voltage to the wire attached to a column and then check the wires attached to each row to see if current is flowing through any of them.  If so, then the switch for a particular button is closed (button pressed).  Then you proceed to the next column and try each row again, etc.  Not rocket science &#8212; just scanning a bunch of switches to see which one is closed.  In fact, there is a <a href="http://www.arduino.cc/playground/Code/Keypad">keypad library in the Arduino Playground</a> that makes it easy to do this.</p>
<p><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/keypad.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/keypad.jpg" alt="" title="keypad" width="480" height="640" class="alignnone size-full wp-image-255" /></a></p>
<p>Well, <a href="https://www.jameco.com/webapp/wcs/stores/servlet/ProductDisplay?productId=2081828">the keypad I bought here</a> has 10 wires instead of 7, and it&#8217;s wired in a really goofy way.  I&#8217;m not sure if this is common, but I thought keypads were generally wired as described above.  Here&#8217;s the schematic that shows how this one is actually wired:<br />
<div id="attachment_249" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/keypadSchematic.png"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/keypadSchematic.png" alt="" title="keypadSchematic" width="640" height="480" class="size-full wp-image-249" /></a><p class="wp-caption-text">Schematic of my non-standard keypad</p></div></p>
<p>Notice that the gray wire is used only for the 9 key.  And the orange wire is only used for the * key.  And the brown wire is only used for the # key.  Why is this built so inefficiently?  I have no idea!</p>
<p>Regardless, here is Arduino code that I used to scan this keypad.  You can do something similar if you have a keypad that is not wired in a straightforward way.</p>
<pre class="codeblockscroll">

// Pins
#define BLACK 2
#define WHITE 3
#define GRAY 4
#define PURPLE 5
#define BLUE 6
#define GREEN 7
#define YELLOW 8
#define ORANGE 9
#define RED 10
#define BROWN 11

#define STAR 10
#define POUND 11

void setup() {
  Serial.begin(115200);

  // Rows
  pinMode(BLACK, INPUT);
  digitalWrite(BLACK, HIGH);  // set pull-up resistors for all inputs

  pinMode(WHITE, INPUT);
  digitalWrite(WHITE, HIGH);

  pinMode(GRAY, INPUT);
  digitalWrite(GRAY, HIGH);

  pinMode(PURPLE, INPUT);
  digitalWrite(PURPLE, HIGH);

  pinMode(ORANGE, INPUT);
  digitalWrite(ORANGE, HIGH);

  pinMode(BROWN, INPUT);
  digitalWrite(BROWN, HIGH);

  // Columns
  pinMode(BLUE, OUTPUT);
  digitalWrite(BLUE, HIGH);

  pinMode(GREEN, OUTPUT);
  digitalWrite(GREEN, HIGH);

  pinMode(YELLOW, OUTPUT);
  digitalWrite(YELLOW, HIGH);

  pinMode(RED, OUTPUT);
  digitalWrite(RED, HIGH);

}

void loop() {
  int key = scanKeypad();

  if (key != -1) {
    if (key == STAR) {
      Serial.println("*");
    } else {
      if (key == POUND) {
        Serial.println("#");
      } else {
          Serial.println(key);
      }
    }
  }
}

int scanKeypad() {
  int key = -1;

  // Pull the first column low, then check each of the rows to see if a
  // button is pressed.
  digitalWrite(BLUE, LOW);
  if (digitalRead(BLACK) == LOW) {
    key = 1;
  }
  if (digitalRead(WHITE) == LOW) {
    key = 4;
  }
  if (digitalRead(PURPLE) == LOW) {
    key = 7;
  }
  digitalWrite(BLUE, HIGH);

  // Moving on to the second column....
  digitalWrite(GREEN, LOW);
  if (digitalRead(BLACK) == LOW) {
    key = 2;
  }
  if (digitalRead(WHITE) == LOW) {
    key = 5;
  }
  if (digitalRead(PURPLE) == LOW) {
    key = 8;
  }
  digitalWrite(GREEN, HIGH);

  // Third "column".  Note that the 0 key is wired to this column even though
  // the 0 is really in the second column.
  digitalWrite(YELLOW, LOW);
  if (digitalRead(BLACK) == LOW) {
    key = 3;
  }
  if (digitalRead(WHITE) == LOW) {
    key = 6;
  }
  if (digitalRead(GRAY) == LOW) {
    key = 9;
  }
  if (digitalRead(PURPLE) == LOW) {
    key = 0;
  }
  digitalWrite(YELLOW, HIGH);

  // Last "column" is not really it's own column.  Only wired to * and #
  digitalWrite(RED, LOW);
  if (digitalRead(ORANGE) == LOW) {
    key = STAR;
  }
  if (digitalRead(BROWN) == LOW) {
    key = POUND;
  }
  digitalWrite(RED, HIGH);

  return key;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://nootropicdesign.com/projectlab/2010/04/03/keypad-tutorial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arduino-Controlled Mood Lamp Made with LEDs and Glass Vials</title>
		<link>http://nootropicdesign.com/projectlab/2010/03/14/mood-lamp/</link>
		<comments>http://nootropicdesign.com/projectlab/2010/03/14/mood-lamp/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 23:08:34 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Art]]></category>
		<category><![CDATA[Level 6]]></category>

		<guid isPermaLink="false">http://nootropicdesign.com/projectlab/?p=154</guid>
		<description><![CDATA[Difficulty Level = 6  [What's this?]
This is a mood lamp I build using 16 LEDs of different colors and small glass vials.  The square bottoms of the vials look a lot like glass block, and the glass diffuses and scatters the light in beautiful ways.  The software shows random patterns of light [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Difficulty Level = 6</em></strong>  <a href="/projectlab/difficulty-levels/">[What's this?]</a></p>
<div id="attachment_151" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/moodLamp1.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/moodLamp1-640x480.jpg" alt="" title="moodLamp1-640x480" width="640" height="480" class="size-full wp-image-151" /></a><p class="wp-caption-text">Arduino Mood Lamp</p></div>
<p>This is a mood lamp I build using 16 LEDs of different colors and small glass vials.  The square bottoms of the vials look a lot like glass block, and the glass diffuses and scatters the light in beautiful ways.  The software shows random patterns of light and the brightness of each LED can vary &#8212; they aren&#8217;t simply &#8220;on&#8221; or &#8220;off&#8221;.</p>
<p>The Arduino code is pretty complex because it implements PWM (pulse-width modulation) for all 16 LEDs.  The Arduino board only has 5 PWM-capable pins, so providing PWM for all 16 pins is accomplished purely in the code.  The lamp randomly displays different lighting patterns and can be really mesmerizing.  Ok, I know you want to see it in action, so here it is (note that the music is just in the background &#8212; the lights are not reacting to it):</p>
<p><object width="640" height="480"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=10145270&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=10145270&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="480"></embed></object>
<p></p>
<h3>Construction</h3>
<p>The base of the lamp is a piece of plexiglass about 5 inches square, and all of the wiring is on the underside of the plexi.  Each of the 16 LEDs goes into a small socket made from two pins of a female header.  I used sockets instead of soldering the LEDs directly so that I could rearrange the colors any way I like.  </p>
<div id="attachment_146" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/fixtures.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/fixtures.jpg" alt="" title="moodlamp-led-sockets" width="640" height="480" class="size-full wp-image-146" /></a><p class="wp-caption-text">LED sockets</p></div><br />
<span id="more-154"></span></p>
<p>Each socket has a 150 ohm resistor soldered in-line so that I could avoid cluttering my breadboard with all those resistors.  The resistor and wires at the base of the socket are covered with a small piece of shrink-wrap tubing to keep it looking clean.</p>
<p><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/inLineResistor.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/inLineResistor.jpg" alt="" title="inLineResistor" width="640" height="480" class="alignnone size-full wp-image-147" /></a></p>
<p>After inserting the LEDs, we have a nice forest of pretty lights!<br />
<div id="attachment_148" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/leds.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/leds-640x480.jpg" alt="" title="leds-640x480" width="640" height="480" class="size-full wp-image-148" /></a><p class="wp-caption-text">Forest of 16 LEDs</p></div>
<p>I got these nice little glass vials at my favorite place for inspiration and great parts: <a href="http://www.ax-man.com/">Ax-Man Surplus</a>.  Take my word for it &#8212; <em>Ax-Man is a maker&#8217;s and hacker&#8217;s paradise</em>.</p>
<div id="attachment_153" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/vials.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/vials.jpg" alt="" title="vials" width="640" height="480" class="size-full wp-image-153" /></a><p class="wp-caption-text">Small glass vials</p></div>
<p></p>
<h3>The Circuit</h3>
<p>There&#8217;s not much to the circuitry of this lamp.  I used two ULN2803A darlington transistor arrays to sink current for the LEDs so that I didn&#8217;t burn out the Arduino board by pulling too much current through the pins.</p>
<div id="attachment_144" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/arduino.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/arduino-640x480.jpg" alt="" title="arduino-moodlamp-circuit-640x480" width="640" height="480" class="size-full wp-image-144" /></a><p class="wp-caption-text">MoodLamp circuit</p></div>
<p></p>
<h3>The Code</h3>
<p>The software running on the Arduino board is where the real magic happens.  If you are an experienced programmer, please <a href="/projectlab/downloads/MoodLamp.pde">look at the full source code</a>.  Like I mentioned before, all 16 LEDs are controlled with software PWM.  This means the LEDs fade in and out smoothly; they don&#8217;t simply blink on and off.  If you hope to understand the code, you&#8217;ll need to really <a href="http://en.wikipedia.org/wiki/Pulse-width_modulation">understand PWM by reading about it</a>.  My code implements a 256 step &#8220;duty cycle&#8221; implemented in the function dutyCycle().  Any LED that is not completely off will be turned on at the beginning of the duty cycle.  If the LED is to be at full brightness, it is never turned off in the 256 step loop.  But if the LED is to be turned on only half the time (thus making it quite a bit dimmer), it is turned off at step 128.  At the end of the 256 step duty cycle, all the LEDs have been on for some portion of the 256 steps.  The sooner it was turned off during the cycle, the dimmer it will appear as the duty cycle is repeated over and over in quick succession.  Look at the code.</p>
<p>The different lighting patterns are called &#8220;visualizations&#8221;.  For example, the visualization &#8220;blinkRandom&#8221; is the one where random LEDs are turned on and then fade out (rather quickly).  The visualization &#8220;throb&#8221; is where each LED pulses on and off slowly at different speeds.  The change in a single LED&#8217;s brightness is determined by a mathematical function that changes over time.  There are 3 math functions available for changing LED brightness over time: linear, sinewave, and exponential.  Each LED has a variable &#8220;dx&#8221; that specifies how fast the LED moves along that function&#8217;s x axis.  For example, for the function &#8216;linear&#8217; and x=128, then y=128.  A y value of 128 means the LED will be on for 128 steps of the 256 step duty cycle (half brightness).  The sine function causes an LED to brighten and dim along a sine wave pattern, and the exponential function is useful for turning on an LED brightly then quickly dimming it with a &#8220;long tail&#8221;.</p>
<p>I&#8217;m not going to explain all the details of the code because it would take many pages (!).    You&#8217;ll need to understand some more advanced topics like <a href="http://en.wikipedia.org/wiki/Function_pointer">function pointers</a>.  Please just <a href="/projectlab/downloads/MoodLamp.pde">have a look for yourself</a> and try to learn from it.  Look at the comments in the code, especially the dutyCycle() function.  Study the blinkRandom() visualization first because it is simple.  I hope you learn something!</p>
]]></content:encoded>
			<wfw:commentRss>http://nootropicdesign.com/projectlab/2010/03/14/mood-lamp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wireless Robotics Platform: Cheap R/C Vehicle + Arduino + XBee + Processing</title>
		<link>http://nootropicdesign.com/projectlab/2010/03/04/wireless-robotics-platform/</link>
		<comments>http://nootropicdesign.com/projectlab/2010/03/04/wireless-robotics-platform/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 03:47:05 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Level 8]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[Robotics]]></category>
		<category><![CDATA[XBee]]></category>

		<guid isPermaLink="false">http://nootropicdesign.com/projectlab/?p=87</guid>
		<description><![CDATA[Difficulty Level = 8  [What's this?]
I built a wireless robotics platform from a cheap R/C car, an Arduino with XBee shield, small microswitch sensors, and a Processing program running on a remote computer to control the vehicle.  The vehicle is completely controlled by the code running on the remote computer which allows very [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Difficulty Level = 8</em></strong>  <a href="/projectlab/difficulty-levels/">[What's this?]</a></p>
<p>I built a wireless robotics platform from a cheap R/C car, an Arduino with XBee shield, small microswitch sensors, and a <a href="http://processing.org">Processing</a> program running on a remote computer to control the vehicle.  The vehicle is completely controlled by the code running on the remote computer which allows very rapid prototyping of the code to tell the vehicle what to do and how to react to the sensor events received from the vehicle.  I&#8217;m hoping this is a good way to teach my 9-year old son about programming.</p>
<div id="attachment_91" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/roverLeftFront1.jpg"><img class="size-full wp-image-91" title="roverLeftFront1_m" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/roverLeftFront1_m.jpg" alt="" width="640" height="480" /></a><p class="wp-caption-text">Wireless computer-controlled robotics platform built on cheap RC vehicle, Arduino microcontroller, and XBee radios</p></div>
<p>Before I get into details, here&#8217;s an overview of the features:</p>
<ul>
<li>All logic controlling the vehicle is performed in a Processing program running on remote computer.  The Arduino program listens for commands from the remote computer.</li>
<li>Bi-directional wireless communication over XBee radios with (theoretical) 1-mile range.  I&#8217;ve accomplished 1/4 mile range with these radios.</li>
<li>Sensor events are transmitted from the vehicle to the controlling computer.  This vehicle has 3 microswitches &#8211; two on front bumper and one at the rear.</li>
<li>Original circuitry of vehicle replaced with dual H-Bridge circuit to control drive motor and turn motor.  Drive motor is controlled with variable speed.</li>
<li>Power: Vehicle motors powered by 4 AA batteries.  Arduino with XBee shield powered by 9V battery mounted at front of vehicle.</li>
<li>Simple communications protocol: 2 byte commands from controller to vehicle, one byte sensor readings from vehicle to controller.</li>
</ul>
<p></p>
<h3>The Hardware</h3>
<p>There&#8217;s nothing special about the configuration of the XBee radios.  They are running the AT firmware (&#8220;transparent mode&#8221;) which allows them to simply exchange serial data.  The Libelium XBee shield on top of the Arduino makes it easy to read/write serial data from Arduino code.<br />
<div id="attachment_90" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/roverTopView.jpg"><img class="size-full wp-image-90" title="roverTopView_m" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/roverTopView_m.jpg" alt="" width="640" height="480" /></a><p class="wp-caption-text">Arduino and XBee shield on top of the vehicle</p></div></p>
<p></p>
<p>Inside the vehicle is a simple circuit board with an L293 quadruple half-H driver to drive the motors.  The drive motor and turn motor are connected.  I had to rip out the original circuit board (but I saved it!).<br />
<span id="more-87"></span><br />
<div id="attachment_102" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/motorController.jpg"><img class="size-full wp-image-102" title="motorController" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/motorController.jpg" alt="" width="640" height="480" /></a><p class="wp-caption-text">Small circuit board with dual H-Bridge chip connected to drive motor and turn motor</p></div></p>
<p></p>
<p>The controller computer connects to an XBee radio via a Sparkfun FTDI USB breakout board.  This is just a simple perf-board circuit connecting the USB interface to the XBee.  It&#8217;s as simple as connecting the RX/TX pairs together, and giving it power.<br />
<div id="attachment_100" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/transmitter.jpg"><img class="size-full wp-image-100" title="transmitter" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/transmitter.jpg" alt="" width="640" height="460" /></a><p class="wp-caption-text">Transmitter on controller computer.  FTDI USB board and XBee radio.</p></div></p>
<p></p>
<p>Here&#8217;s a view of a microswitch collision sensor on the back of the vehicle.   It&#8217;s mounted on a small piece of wood (yes, wood) glued to the chassis.<br />
<div id="attachment_86" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/roverRearSensor-e1263768084116.jpg"><img class="size-full wp-image-86" title="roverRearSensor" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/roverRearSensor-e1263768084116.jpg" alt="" width="640" height="480" /></a><p class="wp-caption-text">Rear collision sensor microswitch</p></div></p>
<p></p>
<h3>The Code</h3>
<p>This is a listing of the Arduino code.  It is fairly simple and self-explanatory because the Arduino just listens for commands and sends sensor readings.  A BEGIN_COMMAND delimiter indicates that the next two bytes are a command.  The first byte of a command is a bit pattern telling the Arduino whether to go forward, backward, turn left, or turn right.  There is one bit assigned to each of those 4 directions (4 bits are unused and reserved for future functions).  The second byte represents speed.  By using PWM on the H-bridge enable pin, the speed of the vehicle can be controlled.<br />
If a sensor switch is closed, then a byte with the appropriate bit is sent back to the controlling computer.  There is logic to debounce the switches.  Studying this code is left as an exercise for the reader.  Feel free to <a href="/projectlab/downloads/XBeeVehicleController.pde">download the Arduino sketch</a>.</p>
<pre class="codeblockscroll">

// Pin assignments
#define LEFT_PIN 13         // red/black
#define TURN_ENABLE_PIN 12  // white
#define DRIVE_ENABLE_PIN 11 // white/black
#define RIGHT_PIN 10        // red
#define BACKWARD_PIN 9      // yellow/black
#define FORWARD_PIN 8       // yellow

#define LEFT_FRONT_BUMPER_PIN 7     // white
#define RIGHT_FRONT_BUMPER_PIN 6    // yellow
#define REAR_BUMPER_PIN 5           // red

// Input Commands
#define BEGIN_COMMAND 0x7F
#define FORWARD 0x1
#define BACKWARD 0x2
#define LEFT 0x4
#define RIGHT 0x8

// Sensor Data
#define LEFT_FRONT_BUMPER 0x1
#define RIGHT_FRONT_BUMPER 0x2
#define REAR_BUMPER 0x4
#define DEBOUNCE_THRESHOLD 50

int sensorData = 0;
int lastSensorData = 0;
int lastLeftFrontBumperReading;
int lastRightFrontBumperReading;
int lastRearBumperReading;
int leftFrontBumperReadingTime;
int rightFrontBumperReadingTime;
int rearBumperReadingTime;
int command[2];

void setup() {
  Serial.begin(9600);

  pinMode(DRIVE_ENABLE_PIN, OUTPUT);
  pinMode(TURN_ENABLE_PIN, OUTPUT);
  pinMode(LEFT_PIN, OUTPUT);
  pinMode(RIGHT_PIN, OUTPUT);
  pinMode(BACKWARD_PIN, OUTPUT);
  pinMode(FORWARD_PIN, OUTPUT);

  pinMode(LEFT_FRONT_BUMPER_PIN, INPUT);
  digitalWrite(LEFT_FRONT_BUMPER_PIN, HIGH);
  pinMode(RIGHT_FRONT_BUMPER_PIN, INPUT);
  digitalWrite(RIGHT_FRONT_BUMPER_PIN, HIGH);
  pinMode(REAR_BUMPER_PIN, INPUT);
  digitalWrite(REAR_BUMPER_PIN, HIGH);

}

void loop() {

  // Read sensors and transmit
  readSensors();
  if (sensorData != lastSensorData) {
    Serial.write(sensorData);
    lastSensorData = sensorData;
  }

  // listen for wireless commands
  if (Serial.available() > 0) {
    if (readCommand() > 0) {
      executeCommand();
    }
  }
}

void readSensors() {
  int s;

  s = digitalRead(LEFT_FRONT_BUMPER_PIN);
  if (s != lastLeftFrontBumperReading) {
    leftFrontBumperReadingTime = millis();
  }
  if ((millis() - leftFrontBumperReadingTime) > DEBOUNCE_THRESHOLD) {
    if (s == LOW) {
      sensorData |= LEFT_FRONT_BUMPER;
    } else {
      sensorData &#038;= ~LEFT_FRONT_BUMPER;
    }
  }
  lastLeftFrontBumperReading = s;

  s = digitalRead(RIGHT_FRONT_BUMPER_PIN);
  if (s != lastRightFrontBumperReading) {
    rightFrontBumperReadingTime = millis();
  }
  if ((millis() - rightFrontBumperReadingTime) > DEBOUNCE_THRESHOLD) {
    if (s == LOW) {
      sensorData |= RIGHT_FRONT_BUMPER;
    } else {
      sensorData &#038;= ~RIGHT_FRONT_BUMPER;
    }
  }
  lastRightFrontBumperReading = s;

  s = digitalRead(REAR_BUMPER_PIN);
  if (s != lastRearBumperReading) {
    rearBumperReadingTime = millis();
  }
  if ((millis() - rearBumperReadingTime) > DEBOUNCE_THRESHOLD) {
    if (s == LOW) {
      sensorData |= REAR_BUMPER;
    } else {
      sensorData &#038;= ~REAR_BUMPER;
    }
  }
  lastRearBumperReading = s;
}

int readCommand() {
  int b = Serial.read();
  if (b == BEGIN_COMMAND) {
    command[0] = readByte();
    command[1] = readByte();
    return 1;
  } else {
    return 0;
  }
}

// blocking read
int readByte() {
  while (true) {
    if (Serial.available() > 0) {
      return Serial.read();
    }
  }
}

void executeCommand() {
  int c = command[0];
  int speed = command[1];

  digitalWrite(DRIVE_ENABLE_PIN, LOW);
  if (c &#038; FORWARD) {
    digitalWrite(BACKWARD_PIN, LOW);
    digitalWrite(FORWARD_PIN, HIGH);
  }
  if (c &#038; BACKWARD) {
    digitalWrite(FORWARD_PIN, LOW);
    digitalWrite(BACKWARD_PIN, HIGH);
  }
  if (c &#038; (FORWARD | BACKWARD)) {
    analogWrite(DRIVE_ENABLE_PIN, speed);
  }

  digitalWrite(TURN_ENABLE_PIN, LOW);
  if (c &#038; LEFT) {
    digitalWrite(RIGHT_PIN, LOW);
    digitalWrite(LEFT_PIN, HIGH);
  }
  if (c &#038; RIGHT) {
    digitalWrite(LEFT_PIN, LOW);
    digitalWrite(RIGHT_PIN, HIGH);
  }
  if (c &#038; (LEFT | RIGHT)) {
    digitalWrite(TURN_ENABLE_PIN, HIGH);
  }
}
</pre>
<p></p>
<p>Now let&#8217;s look at the <a href="http://processing.org">Processing</a> code that really controls the vehicle from afar.  I used Procesing because it&#8217;s easy for beginners, has an IDE that is familiar to Arduino coders, and hides a lot of complexity.  And I&#8217;ve been coding in Java since last century &#8212; Processing is just Java simplified, so it&#8217;s second-nature for me.</p>
<p>This Processing sketch doesn&#8217;t actually have a visual interface at all.  It just communicates with the transmitter via the USB serial interface.  Before I show the entire Processing sketch, I just want to show you the part of the code you write in the <span class="code">draw()</span> method that controls the vehicle.  The <span class="code">draw()</span> method is the same concept as the <span class="code">loop()</span> method in Arduino.  This is how you tell the vehicle what to do:</p>
<pre class="codeblock">
void draw() {

   ...

  speed = 9;  // set speed value.  Valid values are 0-9.
  forward(1000);  // go forward for 1000ms (one second)
  stop();
  right();  // turn wheels
  backward(500);  // backward for half a second
  left();
  speed = 5;
  backward(500);
  stop();
  forward(2000);
  //  you get the idea...

  straight();  // wheels straight
  end();  // end the program.  Without this, it repeats.
}
</pre>
<p>
What about sensor events that we receive from the vehicle?  We handle those by writing methods for each event.  These methods will be called as soon as the sensor reading is received.  The currently running program (like above) will be terminated immediately and the appropriate method below will run.  It looks like we&#8217;re only checking for collision events at the beginning of the <span class="code">draw()</span> method, but when an event happens, the program instructions stop and we come back to the beginning of the <span class="code">draw()</span> immediately so we can handle the event.  Here&#8217;s the full <span class="code">draw()</span> method and the event handling methods:</p>
<pre class="codeblock">
void draw() {

  if (rightFrontBumper) {
    println(timestamp() + " ----RIGHT FRONT IMPACT!----");
    rightFrontBumper();
  }
  if (leftFrontBumper) {
    println(timestamp() + " ----LEFT FRONT IMPACT!-----");
    leftFrontBumper();
  }
  if (rearBumper) {
    println(timestamp() + "-------REAR IMPACT!--------");
    rearBumper();
  }

  speed = 9;  // set speed value.  Valid values are 0-9.
  forward(1000);  // go forward for 1000ms (one second)
  stop();
  right();  // turn wheels
  backward(500);
  left();
  speed = 5;
  backward(500);
  stop();
  forward(2000);
  //  you get the idea...

  straight();  // wheels straight
  end();  // end the program.  Without this, it repeats.
}

void leftFrontBumper() {
  leftFrontBumper = false;
  running = true;
  left();
  speed = 9;
  backward(800);
  straight();
  end();
}

void rightFrontBumper() {
  rightFrontBumper = false;
  running = true;
  right();
  speed = 9;
  backward(800);
  straight();
  end();
}

void rearBumper() {
  rearBumper = false;
  running = true;
  right();
  speed = 9;
  forward(1000);
  straight();
  end();
}
</pre>
<p></p>
<p>You can start your program again by pressing the &#8217;s&#8217; key.  Also, after a program is done running, you can control the vehicle with the arrow keys.  For example, if you want to position the vehicle for another run.</p>
<p>The whole idea here is that this provides a platform for programming the vehicle to do whatever you wish, and dealing with collisions however you want.  There&#8217;s a lot of potential here for more sensors and more commands to the vehicle (How about a robotic arm?  Infrared sensors?).</p>
<p>There&#8217;s a lot more code in the Processing sketch that handles the communication, etc.  Here is an entire listing with simple code for the program to run, and simple event handling methods for collisions.  I won&#8217;t explain every bit of the code, but if you like code, you&#8217;ll be able to understand it.  Feel free to <a href="/projectlab/downloads/XBeeVehicleRemoteControl.pde">download the entire Processing sketch that implements the remote vehicle controller</a>.</p>
<pre class="codeblockscroll">
import processing.serial.*;

Serial port = null;
String portName;
int lastInput = 0;
int[] command = new int[2];
int[] lastCommand = new int[2];
int speed = 9;
int lastSpeed = 0;
int speedStep = (255 - 130) / 8;
boolean running = true;
boolean leftFrontBumper = false;
boolean rightFrontBumper = false;
boolean rearBumper = false;

int DIR_FORWARD = 0x1;
int DIR_BACKWARD = 0x2;
int DIR_LEFT = 0x4;
int DIR_RIGHT = 0x8;
int BEGIN_COMMAND = 0x7F;

// Sensor Data
int LEFT_FRONT_BUMPER = 0x1;
int RIGHT_FRONT_BUMPER = 0x2;
int REAR_BUMPER = 0x4;

SimpleDateFormat df = new SimpleDateFormat("hh:mm:ss.SSS");

void setup() {
  size(1, 1);

  portName = Serial.list()[0];
  try {
    port = new Serial(this, portName, 9600);
  } catch (Exception e) {
    e.printStackTrace();
  }
}

String timestamp() {
  return df.format(new Date());
}

void draw() {

  if (rightFrontBumper) {
    println(timestamp() + " ----RIGHT FRONT IMPACT!----");
    rightFrontBumper();
  }
  if (leftFrontBumper) {
    println(timestamp() + " ----LEFT FRONT IMPACT!-----");
    leftFrontBumper();
  }
  if (rearBumper) {
    println(timestamp() + " -------REAR IMPACT!--------");
    rearBumper();
  }

  speed = 9;
  left();
  forward(1200);
  right();
  forward(800);
  stop();

  left();
  backward(1200);
  stop();
  right();

  forward(2500);
  stop();

  left();
  backward(4000);

  end();
}

void leftFrontBumper() {
  leftFrontBumper = false;
  running = true;

  left();
  speed = 9;
  backward(800);
  straight();
  end();
}

void rightFrontBumper() {
  rightFrontBumper = false;
  running = true;

  right();
  speed = 9;
  backward(800);
  straight();
  end();
}
void rearBumper() {
  rearBumper = false;
  running = true;

  speed = 9;
  forward(1000);
  straight();
  end();
}

void end() {
  if (!running) return;
  stop();
  straight();
  println(timestamp() + " -----------END------------");
  println("Press 's' to restart program or use arrow keys to control vehicle.");
  running = false;
}

void interruptibleDelay(int millis) {
  int start = millis();
  int d;
  while (running) {
    int timeLeftToWait = millis-(millis()-start);
    d = min(10, timeLeftToWait);
    if (d <= 0) return;
    delay(d);
  }
}

void forward(int millis) {
  if (!running) return;
  forward();
  interruptibleDelay(millis);
  stop();
}

void forward() {
  if (!running) return;
  doForward();
}

void doForward() {
  command[0] = command[0] &#038; ~DIR_BACKWARD;
  command[0] = command[0] | DIR_FORWARD;
  sendCommand();
}

void backward(int millis) {
  if (!running) return;
  doBackward();
  interruptibleDelay(millis);
  stop();
}

void backward() {
  if (!running) return;
  doBackward();
}

void doBackward() {
  command[0] = command[0] &#038; ~DIR_FORWARD;
  command[0] = command[0] | DIR_BACKWARD;
  sendCommand();
}

void left() {
  if (!running) return;
  doLeft();
}

void doLeft() {
  command[0] = command[0] &#038; ~DIR_RIGHT;
  command[0] = command[0] | DIR_LEFT;
  sendCommand();
}

void right() {
  if (!running) return;
  doRight();
}

void doRight() {
  command[0] = command[0] &#038; ~DIR_LEFT;
  command[0] = command[0] | DIR_RIGHT;
  sendCommand();
}

void straight() {
  if (!running) return;
  doStraight();
}

void doStraight() {
  command[0] = command[0] &#038; ~DIR_RIGHT;
  command[0] = command[0] &#038; ~DIR_LEFT;
  sendCommand();
}

void stop() {
  if (!running) return;
  doStop();
}
void doStop() {
  command[0] = command[0] &#038; ~DIR_BACKWARD;
  command[0] = command[0] &#038; ~DIR_FORWARD;
  sendCommand();
}

void serialEvent(Serial p) {
  int input = p.read();
  lastInput = input;
  processInput(input);
} 

void processInput(int input) {
  if ((input &#038; LEFT_FRONT_BUMPER) != 0) {
    stop();
    leftFrontBumper = true;
    running = false;
  }

  if ((input &#038; RIGHT_FRONT_BUMPER) != 0) {
    stop();
    rightFrontBumper = true;
    running = false;
  }

  if ((input &#038; REAR_BUMPER) != 0) {
    stop();
    rearBumper = true;
    running = false;
  }
}

void sendCommand() {
  if (!isNewCommand()) {
    return;
  }
  if (port != null) {
    port.write(BEGIN_COMMAND);
    port.write(command[0]);
    command[1] = 255 - ((9 - speed) * speedStep);
    port.write(command[1]);
    if ((command[0] &#038; DIR_FORWARD) > 0) {
      print(timestamp() + " FORWARD\t");
    }
    if ((command[0] &#038; DIR_BACKWARD) > 0) {
      print(timestamp() + " BACKWARD\t");
    }
    if (((command[0] &#038; DIR_FORWARD) == 0) &#038;&#038; ((command[0] &#038; DIR_BACKWARD) == 0)) {
      print(timestamp() + " STOP\t");
    }
    if ((command[0] &#038; DIR_LEFT) > 0) {
      print("LEFT\t");
    }
    if ((command[0] &#038; DIR_RIGHT) > 0) {
      print("RIGHT\t");
    }
    if (((command[0] &#038; DIR_LEFT) == 0) &#038;&#038; ((command[0] &#038; DIR_RIGHT) == 0)) {
      print("STRAIGHT\t");
    }
    println("SPEED=" + speed);

    lastCommand[0] = command[0];
    lastCommand[1] = command[1];
    lastSpeed = speed;
  }
}

boolean isNewCommand() {
  return ((command[0] != lastCommand[0]) || (command[1] != lastCommand[1]) || (speed != lastSpeed));
}

void keyPressed() {
  if (key == CODED) {
    if (keyCode == UP) {
      doForward();
    }
    if (keyCode == DOWN) {
      doBackward();
    }
    if (keyCode == LEFT) {
      doLeft();
    }
    if (keyCode == RIGHT) {
      doRight();
    }
  }
  if ((key >= '1') &#038;&#038; (key <= '9')) {
    speed = 9 - ('9' - key);
    println("set speed = " + speed);
  }
  if (key == 's') {
    running = true;
  }
}

void keyReleased() {
  if (key == CODED) {
    if (keyCode == UP) {
      doStop();
    }
    if (keyCode == DOWN) {
      doStop();
    }
    if (keyCode == LEFT) {
      doStraight();
    }
    if (keyCode == RIGHT) {
      doStraight();
    }
  }
}
</pre>
<h3>Demo</h3>
<p>Here's a demo where I tried to program the vehicle to negotiate an obstacle course.  This is the instructions and the sensor event handling code:</p>
<pre class="codeblockscroll">
void draw() {

  if (rightFrontBumper) {
    println(timestamp() + " ----RIGHT FRONT IMPACT!----");
    rightFrontBumper();
  }
  if (leftFrontBumper) {
    println(timestamp() + " ----LEFT FRONT IMPACT!-----");
    leftFrontBumper();
  }
  if (rearBumper) {
    println(timestamp() + " -------REAR IMPACT!--------");
    rearBumper();
  }

  speed = 9;
  left();
  forward(1200);
  right();
  forward(800);
  stop();

  left();
  backward(1200);
  stop();
  right();

  forward(2500);
  stop();

  left();
  backward(4000);

  end();
}

void leftFrontBumper() {
  leftFrontBumper = false;
  running = true;

  left();
  speed = 9;
  backward(800);
  straight();
  end();
}

void rightFrontBumper() {
  rightFrontBumper = false;
  running = true;

  right();
  speed = 9;
  backward(800);
  straight();
  end();
}

void rearBumper() {
  rearBumper = false;
  running = true;

  speed = 9;
  forward(1000);
  straight();
  end();
}
</pre>
<p>Let's see how well it worked.  I tried to navigate through the cones without hitting them.  The wheels skidded a bit when changing direction on the smooth floor.  At the end, I purposefully ran into something backwards to demonstrate a sensor event.  See if you can match up the vehicle's actions with the code above.<br />
<object width="640" height="480"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8937750&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8937750&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="480"></embed></object></p>
<p>Finally, here's a screenshot of the Processing console that shows everything that happened.  Notice the rear impact event at the end.<br />
<a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/vehicleControllerConsole.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/vehicleControllerConsole.jpg" alt="" title="vehicleControllerConsole" width="640" height="297" class="alignnone size-full wp-image-122" /></a></p>
<p>Hope you enjoyed reading about this project.  It was a lot of work and I hope that it can be the basis for future robotics experimentation.</p>
]]></content:encoded>
			<wfw:commentRss>http://nootropicdesign.com/projectlab/2010/03/04/wireless-robotics-platform/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>EZ-Expander Shield for Arduino</title>
		<link>http://nootropicdesign.com/projectlab/2010/03/03/ez-expander/</link>
		<comments>http://nootropicdesign.com/projectlab/2010/03/03/ez-expander/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 02:21:57 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Arduino]]></category>

		<guid isPermaLink="false">http://nootropicdesign.com/projectlab/?p=133</guid>
		<description><![CDATA[I&#8217;m happy to finally announce my new product, the EZ-Expander shield.  After several months of hard work of sourcing parts, designing the PCB, and setting up a store, my first product is now available for purchase in the nootropic design store! 
For all the technical details, go to the EZ-Expander page.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to finally announce my new product, the EZ-Expander shield.  After several months of hard work of sourcing parts, designing the PCB, and setting up a store, my first product is now available for purchase in the <a href="http://nootropicdesign.com/store/">nootropic design store</a>! </p>
<p><a href="http://nootropicdesign.com/ez-expander/">For all the technical details, go to the EZ-Expander page.</a></p>
<div id="attachment_136" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/ez-expander-assembled-640x480.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/ez-expander-assembled-640x480.jpg" alt="" title="EZ-Expander shield" width="640" height="480" class="size-full wp-image-136" /></a><p class="wp-caption-text">EZ-Expander shield</p></div><br />
<div id="attachment_137" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/ez-expander-arduino-640x480.jpg"><img src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/03/ez-expander-arduino-640x480.jpg" alt="" title="EZ-Expander on Arduino" width="640" height="480" class="size-full wp-image-137" /></a><p class="wp-caption-text">EZ-Expander on an Arduino</p></div>
]]></content:encoded>
			<wfw:commentRss>http://nootropicdesign.com/projectlab/2010/03/03/ez-expander/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arduino Police Lights</title>
		<link>http://nootropicdesign.com/projectlab/2010/01/08/arduino-police-lights/</link>
		<comments>http://nootropicdesign.com/projectlab/2010/01/08/arduino-police-lights/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 04:03:23 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Level 4]]></category>

		<guid isPermaLink="false">http://nootropicdesign.com/projectlab/?p=70</guid>
		<description><![CDATA[Difficulty Level = 4  [What's this?]
This is an amusing project inspired by flashing blue and red lights on police cars, ambulances, etc.  This is a perf board Arduino with 5 blue and 5 red LEDs, and the Arduino code lights them up in a pattern similar to police lights.
First, the Arduino built on a [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Difficulty Level = 4</em></strong>  <a href="/projectlab/difficulty-levels/">[What's this?]</a></p>
<p>This is an amusing project inspired by flashing blue and red lights on police cars, ambulances, etc.  This is a perf board Arduino with 5 blue and 5 red LEDs, and the Arduino code lights them up in a pattern similar to police lights.</p>
<p>First, the Arduino built on a perf board.  It&#8217;s not hard to build your own Arduino.  I use a real Arduino board to upload code to the ATMega328 chip, then just move it to the project board.</p>
<div id="attachment_73" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/policeLights.jpg"><img class="size-full wp-image-73" title="policeLights" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2010/01/policeLights.jpg" alt="" width="640" height="480" /></a><p class="wp-caption-text">Perfboard Arduino with blue and red LEDs for police lights mini-project</p></div>
<p>Now here it is in action &#8212; I really think if you don&#8217;t know what you&#8217;re looking at, it looks realistic in the dark.</p>
<p><object width="640" height="480"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8628039&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8628039&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="480"></embed></object></p>
<p>Here&#8217;s the code that makes it work.  Notice that some of the LEDs are controlled using PWM; the second and fourth LED in each of the blue and red groups.  I would invite people to build something similar and tweak this to get the most realistic effect possible!</p>
<pre class="codeblockscroll">
#define NUM_OFF 3
#define DELAY 50
#define PWM_MIN 10
#define PWM_MAX 128

int blue[5];
int red[5];

void setup()
{
  blue[0] = 19;
  blue[1] = 5;
  blue[2] = 18;
  blue[3] = 6;
  blue[4] = 17;
  red[0] = 13;
  red[1] = 11;
  red[2] = 12;
  red[3] = 10;
  red[4] = 9;

  for(int i=0;i<5;i++) {
    pinMode(blue[i], OUTPUT);
    pinMode(red[i], OUTPUT);
  }
  randomSeed(analogRead(0));
}

void loop()
{
  allOn();
  analogWrite(blue[1], random(PWM_MIN, PWM_MAX));
  analogWrite(blue[3], random(PWM_MIN, PWM_MAX));
  analogWrite(red[1], random(PWM_MIN, PWM_MAX));
  analogWrite(red[3], random(PWM_MIN, PWM_MAX));

  for(int i=0;i&lt;NUM_OFF;i++) {
    digitalWrite(blue[random(5)], LOW);
    digitalWrite(red[random(5)], LOW);
  }
  delay(DELAY);
}

void allOn() {
  for(int i=0;i&lt;5;i++) {
    digitalWrite(blue[i], HIGH);
    digitalWrite(red[i], HIGH);
  }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://nootropicdesign.com/projectlab/2010/01/08/arduino-police-lights/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arduino-Controlled Lock with Keypad</title>
		<link>http://nootropicdesign.com/projectlab/2009/11/23/arduino-controlled-coded-lock/</link>
		<comments>http://nootropicdesign.com/projectlab/2009/11/23/arduino-controlled-coded-lock/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 13:51:54 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Level 6]]></category>

		<guid isPermaLink="false">http://nootropicdesign.com/projectlab/?p=39</guid>
		<description><![CDATA[Difficulty Level = 6  [What's this?]
After tearing down an old CD player, I was inspired by the CD laser scanning assembly to build a door lock for my subterranean lab.  The assembly has two motors: one for turning the CD (I&#8217;m not using this one) and one for slowly moving the laser across [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Difficulty Level = 6</em></strong>  <a href="/projectlab/difficulty-levels/">[What's this?]</a></p>
<p>After tearing down an old CD player, I was inspired by the CD laser scanning assembly to build a door lock for my subterranean lab.  The assembly has two motors: one for turning the CD (I&#8217;m not using this one) and one for slowly moving the laser across the CD&#8217;s surface.  This second motor provides a nice linear motion that I wanted to use to build an electronically-controlled dead bolt lock for my lab.</p>
<p>Here&#8217;s the assembled lock.  The circuit board in the middle is an H-bridge circuit I built to allow the motor to move in both directions.  There are two position sensing switches so the Arduino senses when the motor has reached its limit in either direction.  A 9V power supply powers the Arduino board, and a separate 5V supply drives the motor through the H-bridge.  The dead bolt is <em>literally</em> a bolt &#8212; connected to the assembly with a piece of scrap circuit board &#8212; that travels through the door jamb and into the door.</p>
<div id="attachment_44" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2009/11/lockClosed.jpg"><img class="size-full wp-image-44" title="lockClosed-sm" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2009/11/lockClosed-sm.jpg" alt="The lock in the closed (locked) position." width="640" height="853" /></a><p class="wp-caption-text">The lock in the closed (locked) position.</p></div>
<p>The black CAT5 cable connected to pins 2-8 goes through a small hole in the wall (under a desk) to the keypad on the outside of the lab (I wasn&#8217;t sure I wanted to permanently mount the keypad in the wall).  The user types in the correct code and presses the # key to open or close the lock.  The green LED indicates the door is unlocked.  Red indicates locked.  </p>
<div id="attachment_29" class="wp-caption alignnone" style="width: 650px"><a href="http://nootropicdesign.com/projectlab/wp-content/uploads/2009/11/keypad.jpg"><img class="size-full wp-image-29" title="keypad" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2009/11/keypad.jpg" alt="Lock keypad - green indicates that it's unlocked, red indicates locked." width="640" height="480" /></a><p class="wp-caption-text">Lock keypad - green indicates that it&#39;s unlocked, red indicates locked.</p></div>
<p>Let&#8217;s see the lock in action.  (While recording, I gave instructions to my son to lock and unlock using the keypad off camera.)<br />
<object width="640" height="480"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=7504447&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=7504447&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="480"></embed></object></p>
<p><span id="more-39"></span><br />
Reading the keypad is by far the most complicated thing in the Arduino code below.  They keypad has 12 keys but only 10 wires.  Reading the keypad is not as simple as checking to see which of the 12 switches is closed.  The keys must be constantly scanned to see which if any keys are depressed.   Scanning the keypad is done by multiplexing through 6 of the wires on the keypad, alternately setting them LOW and then checking the other 4 wires (blue, green, yellow, red) on the keypad to see if a button is pressed.  </p>
<p>A shift register on the keypad lets me control 8 outputs with only 3 Arduino pins: the latch pin, clock pin and data pin.  The eight outputs are 6 multiplexed wires of the keypad plus one for each LED.  The total number of wires running to the keypad is 3 for the output (latch, clock, data), 4 inputs, 5V, and GND.  That&#8217;s 9 total, and since CAT5 has only 8 wires, I have the 9th wire (GND) taped to the CAT5.  Hey, it got the job done.</p>
<pre class="codeblockscroll">
#define LATCH_PIN 2
#define CLOCK_PIN 3
#define DATA_PIN 4

// Keypad inputs (colors are keypad wires, not cat5 wires)
#define BLUE_PIN 5
#define GREEN_PIN 6
#define YELLOW_PIN 7
#define RED_PIN 8

// PNP transistors.  LOW to activate.
#define Q1 17
#define Q2 19

// NPN transistors.  HIGH to activate.
#define Q3 16
#define Q4 18

#define LOCK_LIMIT_SWITCH_PIN 15  // long wires
#define UNLOCK_LIMIT_SWITCH_PIN 14

#define LOCKED 0
#define UNLOCKED 1
#define LOCKING 2
#define UNLOCKING 3

#define NO_SCAN 0xFC
#define BLACK 0x80
#define WHITE 0x40
#define GRAY 0x20
#define PURPLE 0x10
#define ORANGE 0x8
#define BROWN 0x4
#define GREEN_LED_ON 0x2
#define RED_LED_ON 0x1

#define NO_KEY -1
#define STAR 10
#define POUND 11

int state;
byte greenLED = 0;
byte redLED = RED_LED_ON;
int lastKey = -1;

#define MAX_GUESS 10
#define COMBO_LENGTH 4

int code[COMBO_LENGTH] = {5, 6, 1, 8};
int guess[MAX_GUESS];
int guessIndex = 0;

void setup() {
  pinMode(LATCH_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  pinMode(DATA_PIN, OUTPUT);

  pinMode(BLUE_PIN, INPUT);
  digitalWrite(BLUE_PIN, HIGH); // set pull-up resistor
  pinMode(GREEN_PIN, INPUT);
  digitalWrite(GREEN_PIN, HIGH); // set pull-up resistor
  pinMode(YELLOW_PIN, INPUT);
  digitalWrite(YELLOW_PIN, HIGH); // set pull-up resistor
  pinMode(RED_PIN, INPUT);
  digitalWrite(RED_PIN, HIGH); // set pull-up resistor

  pinMode(Q1, OUTPUT);
  pinMode(Q2, OUTPUT);
  pinMode(Q3, OUTPUT);
  pinMode(Q4, OUTPUT);

  pinMode(UNLOCK_LIMIT_SWITCH_PIN, INPUT);
  digitalWrite(UNLOCK_LIMIT_SWITCH_PIN, HIGH); // set pull-up resistor

  pinMode(LOCK_LIMIT_SWITCH_PIN, INPUT);
  digitalWrite(LOCK_LIMIT_SWITCH_PIN, HIGH); // set pull-up resistor

  unlock();

}

void loop() {
  if ((isUnlocked()) &amp;&amp; (state == UNLOCKING)) {
    stop();
    state = UNLOCKED;
  }
  if ((isLocked()) &amp;&amp; (state == LOCKING)) {
    stop();
    state = LOCKED;
  }

  if ((state != UNLOCKING) &amp;&amp; (state != LOCKING)) {
    int n = scanKeypad();
    if (n != lastKey) {
      // something changed
      if (n == NO_KEY) {
        // key released
        processKey(lastKey);
      }
      lastKey = n;
    }
  }
}

int scanKeypad() {

  writeData((NO_SCAN ^ BLACK) | redLED | greenLED);
  if (digitalRead(BLUE_PIN) == LOW) {
    return POUND;
  }
  if (digitalRead(GREEN_PIN) == LOW) {
    return 0;
  }
  if (digitalRead(YELLOW_PIN) == LOW) {
    return STAR;
  }

  writeData((NO_SCAN ^ WHITE) | redLED | greenLED);
  if (digitalRead(BLUE_PIN) == LOW) {
    return 9;
  }
  if (digitalRead(GREEN_PIN) == LOW) {
    return 8;
  }
  if (digitalRead(YELLOW_PIN) == LOW) {
    return 7;
  }

  writeData((NO_SCAN ^ GRAY) | redLED | greenLED);
  if (digitalRead(YELLOW_PIN) == LOW) {
    return 4;
  }

  writeData((NO_SCAN ^ PURPLE) | redLED | greenLED);
  if (digitalRead(BLUE_PIN) == LOW) {
    return 6;
  }
  if (digitalRead(GREEN_PIN) == LOW) {
    return 5;
  }
  if (digitalRead(YELLOW_PIN) == LOW) {
    return 2;
  }

  writeData((NO_SCAN ^ ORANGE) | redLED | greenLED);
  if (digitalRead(RED_PIN) == LOW) {
    return 3;
  }

  writeData((NO_SCAN ^ BROWN) | redLED | greenLED);
  if (digitalRead(RED_PIN) == LOW) {
    return 1;
  }

  return NO_KEY;
}  

void processKey(int k) {
  if ((k != POUND) &amp;&amp; (k != STAR)) {
    guess[guessIndex++] = k;
    if (guessIndex == MAX_GUESS) {
      clearGuess();
      blinkRed(3);
    }
  }
  if (k == POUND) {
    if (guessIsCorrect()) {
      if (state == LOCKED) {
        greenLED = GREEN_LED_ON;
        redLED = 0;
        unlock();
      } else {
        if (state == UNLOCKED) {
          greenLED = 0;
          redLED = RED_LED_ON;;
          lock();
        }
      }
      blinkGreen(3);
      clearGuess();
    } else {
      clearGuess();
      blinkRed(3);
    }
  }
}

void clearGuess() {
  guessIndex = 0;
  for(int i=0; i &lt; MAX_GUESS; i++) {
    guess[i] = -1;
  }
}

boolean guessIsCorrect() {
  for(int i=0; i &lt; COMBO_LENGTH; i++) {
    if (guess[i] != code[i]) {
      return false;
    }
  }
  return true;
}

void blinkRed(int n) {
  for(int i=0; i &lt; n; i++) {
    writeData(NO_SCAN);
    delay(100);
    writeData(NO_SCAN | RED_LED_ON);
    delay(100);
  }
}

void blinkGreen(int n) {
  for(int i=0; i &lt; n; i++) {
    writeData(NO_SCAN);
    delay(100);
    writeData(NO_SCAN | GREEN_LED_ON);
    delay(100);
  }
}

void writeData(byte data) {
  digitalWrite(LATCH_PIN, LOW);
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, data);
  digitalWrite(LATCH_PIN, HIGH);
}

boolean isUnlocked() {
  return (digitalRead(UNLOCK_LIMIT_SWITCH_PIN) == LOW);
}

boolean isLocked() {
  return (digitalRead(LOCK_LIMIT_SWITCH_PIN) == LOW);
}

void unlock() {
  digitalWrite(Q2, HIGH);  // OFF
  digitalWrite(Q3, LOW);   // OFF
  digitalWrite(Q1, LOW);   // ON
  digitalWrite(Q4, HIGH);  // ON
  state = UNLOCKING;
}

void lock() {
  digitalWrite(Q1, HIGH);  // OFF
  digitalWrite(Q4, LOW);   // OFF
  digitalWrite(Q2, LOW);   // ON
  digitalWrite(Q3, HIGH);  // ON
  state = LOCKING;
}

void stop() {
  digitalWrite(Q1, HIGH);  // OFF
  digitalWrite(Q2, HIGH);  // OFF
  digitalWrite(Q3, LOW);   // OFF
  digitalWrite(Q4, LOW);   // OFF
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://nootropicdesign.com/projectlab/2009/11/23/arduino-controlled-coded-lock/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Wireless Temperature Sensor</title>
		<link>http://nootropicdesign.com/projectlab/2009/11/01/wireless-temperature-sensor/</link>
		<comments>http://nootropicdesign.com/projectlab/2009/11/01/wireless-temperature-sensor/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 18:50:49 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Level 5]]></category>
		<category><![CDATA[XBee]]></category>

		<guid isPermaLink="false">http://nootropicdesign.com/projectlab/?p=14</guid>
		<description><![CDATA[Difficulty Level = 5  [What's this?]
I decided to explore the more advanced features of XBee radios by building a remote temperature sensor.  You can get quite a bit of control over an XBee radio without a microcontroller at all.  You can configure the radio to send sensor readings at particular intervals when [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Difficulty Level = 5</em></strong>  <a href="/projectlab/difficulty-levels/">[What's this?]</a></p>
<p>I decided to explore the more advanced features of <a href="http://www.digi.com/products/wireless/zigbee-mesh/">XBee</a> radios by building a remote temperature sensor.  You can get quite a bit of control over an XBee radio without a microcontroller at all.  You can configure the radio to send sensor readings at particular intervals when it detects changes on certain input pins.  For the details on configuring XBee radios, see the <a href="http://ftp1.digi.com/support/documentation/90000982_B.pdf">documentation at Digi International</a>.</p>
<p>For this project, I configured the radio at the sensor end to read the analog input of pin 19 every 4 seconds and to send a sensor reading packet.  Both the sender and receiver radios should be running the API firmware.  Input pin 19 on my sensor radio is configured (parameter D1) with value &#8216;2&#8242; which means that it will read analog input, and the IO sampling rate (parameter IR) is set to &#8216;1000&#8242; which sends a sample every 4096ms.</p>
<p>An LM34 temperature sensor outputs a variable voltage depending on the temperature.  The mapping is extremely simple: 10mV for every Fahrenheit degree.  So, at 72 degrees F, the output is 720mV.</p>
<p>Why did I choose pin 19?  I started with pin 20, but I burned it out.  The pins can only handle an analog input of up to 1.2V, and I <em>think</em> I may have sent too much into the pin.  How?  Well, let&#8217;s say it involved holding a cold Pepsi can on the circuit to cool off the temperature sensor, and I shorted out a connection with the can.  Oops.  I&#8217;m lucky I didn&#8217;t burn out the entire XBee chip.</p>
<div id="attachment_5" class="wp-caption alignnone" style="width: 650px"><img class="size-full wp-image-5" title="sensor" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2009/11/sensor.jpg" alt="Remote temperature sensor" width="640" height="480" /><p class="wp-caption-text">Remote temperature sensor</p></div>
<p>Here is the circuit for the remote sensor:</p>
<div id="attachment_6" class="wp-caption alignnone" style="width: 623px"><img class="size-full wp-image-6" title="sensorSchematic" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2009/11/sensorSchematic1.png" alt="Schematic for remote sensor circuit" width="613" height="481" /><p class="wp-caption-text">Schematic for remote sensor circuit</p></div>
<p>For the receiving side, I used an Arduino with an XBee shield and a two digit LED display:<br />
<span id="more-14"></span></p>
<div id="attachment_7" class="wp-caption alignnone" style="width: 650px"><img class="size-full wp-image-7" title="display" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2009/11/display.jpg" alt="Arduino with XBee shield and LED display" width="640" height="480" /><p class="wp-caption-text">Arduino with XBee shield and LED display</p></div>
<p>Here&#8217;s the Arduino code for reading incoming packets from the XBee and displaying the received analog sample on the LED display.  Parsing an XBee packet is quite complex, unfortunately.  But after studying the documentation for a while, it isn&#8217;t that hard.</p>
<pre class="codeblockscroll">#define NUM_DIGITAL_SAMPLES 12
#define NUM_ANALOG_SAMPLES 4

int groundPins[7] = {8, 2, 3, 4, 5, 9, 7};
int digitPins[2] = {11, 10};
int ON = HIGH;
int OFF = LOW;
int number[10][7];
int digit[2];
int TOP = 0;
int UPPER_L = 1;
int LOWER_L = 2;
int BOTTOM = 3;
int LOWER_R = 4;
int UPPER_R = 5;
int MIDDLE = 6;

int index;
int n = 0;

int packet[32];
int digitalSamples[NUM_DIGITAL_SAMPLES];
int analogSamples[NUM_ANALOG_SAMPLES];

void setup()
{
  Serial.begin(9600);

  for(int i=0;i&lt;7;i++) {
    pinMode(groundPins[i], OUTPUT);
  }
  for(int i=0;i&lt;2;i++) {
    pinMode(digitPins[i], OUTPUT);
  }
  initNumber();

  setDigit(n);
}

void loop() {
  readPacket();
  drawDisplay();
}

void readPacket() {
  if (Serial.available() &gt; 0) {
    int b = Serial.read();
    if (b == 0x7E) {
      packet[0] = b;
      packet[1] = readByte();
      packet[2] = readByte();
      int dataLength = (packet[1] &lt;&lt; 8) | packet[2];

      for(int i=1;i&lt;=dataLength;i++) {
        packet[2+i] = readByte();
      }
      int apiID = packet[3];
      packet[3+dataLength] = readByte(); // checksum

      printPacket(dataLength+4);

      if (apiID == 0x92) {
        int analogSampleIndex = 19;
        int digitalChannelMask = (packet[16] &lt;&lt; 8) | packet[17];
        if (digitalChannelMask &gt; 0) {
          int d = (packet[19] &lt;&lt; 8) | packet[20];
          for(int i=0;i &lt; NUM_DIGITAL_SAMPLES;i++) {
            digitalSamples[i] = ((d &gt;&gt; i) &amp; 1);
          }
          analogSampleIndex = 21;
        }

        int analogChannelMask = packet[18];
        for(int i=0;i&lt;4;i++) {
          if ((analogChannelMask &gt;&gt; i) &amp; 1) {
            analogSamples[i] = (packet[analogSampleIndex] &lt;&lt; 8) | packet[analogSampleIndex+1];
            analogSampleIndex += 2;
          } else {
            analogSamples[i] = -1;
          }
        }
      }
    }

    int reading = analogSamples[1];  // pin 19
    // convert reading to millivolts
    float v = ((float)reading/(float)0x3FF)*1200.0;

    // convert to Fahrenheit.  10mv per Fahrenheit degree
    float f = v / 10.0;

    // round to nearest int
    n = (int)(f+0.5);
    setDigit(n);
  }
}

void drawDisplay() {
  for(int g=0;g&lt;7;g++) {
    digitalWrite(groundPins[g], LOW);
    for(int i=0;i&lt;2;i++) {
      if (digit[i] &lt; 0) {
        continue;
      }
      digitalWrite(digitPins[i], number[digit[i]][g]);
    }
    delay(0);  // for some reason, this is required even if the value is 0
    digitalWrite(groundPins[g], HIGH);
  }
}

void setDigit(int n) {
  n = n % 100;
  digit[0] = n % 10;
  digit[1] = (n / 10) % 10;
  if ((digit[1] == 0) &amp;&amp; (n &lt; 10)) {
    digit[1] = -1;
  }
}

void initNumber() {
  number[0][0] = ON;
  number[0][1] = ON;
  number[0][2] = ON;
  number[0][3] = ON;
  number[0][4] = ON;
  number[0][5] = ON;
  number[0][6] = OFF;

  number[1][0] = OFF;
  number[1][1] = OFF;
  number[1][2] = OFF;
  number[1][3] = OFF;
  number[1][4] = ON;
  number[1][5] = ON;
  number[1][6] = OFF;

  number[2][0] = ON;
  number[2][1] = OFF;
  number[2][2] = ON;
  number[2][3] = ON;
  number[2][4] = OFF;
  number[2][5] = ON;
  number[2][6] = ON;

  number[3][0] = ON;
  number[3][1] = OFF;
  number[3][2] = OFF;
  number[3][3] = ON;
  number[3][4] = ON;
  number[3][5] = ON;
  number[3][6] = ON;

  number[4][0] = OFF;
  number[4][1] = ON;
  number[4][2] = OFF;
  number[4][3] = OFF;
  number[4][4] = ON;
  number[4][5] = ON;
  number[4][6] = ON;

  number[5][0] = ON;
  number[5][1] = ON;
  number[5][2] = OFF;
  number[5][3] = ON;
  number[5][4] = ON;
  number[5][5] = OFF;
  number[5][6] = ON;

  number[6][0] = ON;
  number[6][1] = ON;
  number[6][2] = ON;
  number[6][3] = ON;
  number[6][4] = ON;
  number[6][5] = OFF;
  number[6][6] = ON;

  number[7][0] = ON;
  number[7][1] = OFF;
  number[7][2] = OFF;
  number[7][3] = OFF;
  number[7][4] = ON;
  number[7][5] = ON;
  number[7][6] = OFF;

  number[8][0] = ON;
  number[8][1] = ON;
  number[8][2] = ON;
  number[8][3] = ON;
  number[8][4] = ON;
  number[8][5] = ON;
  number[8][6] = ON;

  number[9][0] = ON;
  number[9][1] = ON;
  number[9][2] = OFF;
  number[9][3] = ON;
  number[9][4] = ON;
  number[9][5] = ON;
  number[9][6] = ON;
}
void printPacket(int l) {
  for(int i=0;i &lt; l;i++) {
    if (packet[i] &lt; 0xF) {
      // print leading zero for single digit values
      Serial.print(0);
    }
    Serial.print(packet[i], HEX);
    Serial.print(" ");
  }
  Serial.println("");
} 

int readByte() {
    while (true) {
      if (Serial.available() &gt; 0) {
      return Serial.read();
    }
  }
}</pre>
<p>Here&#8217;s how I wired the back of the LED display.  The code displays each digit separately to save Arduino pins but toggles between the digits so fast you can&#8217;t see any flicker.</p>
<div id="attachment_8" class="wp-caption alignnone" style="width: 650px"><img class="size-full wp-image-8" title="displayCircuit" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2009/11/displayCircuit.jpg" alt="Back of LED display.  The pin positions are designed to fit the XBee shield." width="640" height="480" /><p class="wp-caption-text">Back of LED display.  The pin positions are designed to fit the XBee shield.</p></div>
<p>Here&#8217;s how it looks in the dark!</p>
<div id="attachment_9" class="wp-caption alignnone" style="width: 650px"><img class="size-full wp-image-9" title="display-dark" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2009/11/display-dark.jpg" alt="In the dark!" width="640" height="480" /><p class="wp-caption-text">In the dark!</p></div>
]]></content:encoded>
			<wfw:commentRss>http://nootropicdesign.com/projectlab/2009/11/01/wireless-temperature-sensor/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Hack-a-Sketch</title>
		<link>http://nootropicdesign.com/projectlab/2009/10/31/hack-a-sketch/</link>
		<comments>http://nootropicdesign.com/projectlab/2009/10/31/hack-a-sketch/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 13:45:28 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Level 5]]></category>
		<category><![CDATA[Processing]]></category>

		<guid isPermaLink="false">http://nootropicdesign.com/projectlab/?p=12</guid>
		<description><![CDATA[Difficulty Level = 5  [What's this?]
Here is a device I call the Hack-a-Sketch.  The screen is a normal laptop (an old one), but it has real knobs which control the stylus on the screen.
An Arduino board reads the inputs from two potentiometers (the knobs), and sends the information via USB to a Processing [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Difficulty Level = 5</em></strong>  <a href="/projectlab/difficulty-levels/">[What's this?]</a></p>
<p>Here is a device I call the Hack-a-Sketch.  The screen is a normal laptop (an old one), but it has real knobs which control the stylus on the screen.</p>
<div id="attachment_3" class="wp-caption alignnone" style="width: 650px"><img class="size-full wp-image-3" title="hackasketch" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2009/11/hackasketch.jpg" alt="The Hack-a-Sketch" width="640" height="480" /><p class="wp-caption-text">The Hack-a-Sketch</p></div>
<p>An <a href="http://www.arduino.cc/">Arduino</a> board reads the inputs from two potentiometers (the knobs), and sends the information via USB to a <a href="http://processing.org/">Processing</a> sketch which displays the path of the stylus on the screen.  This was extremely easy to build because the Arduino is just running the StandardFirmata firmware.  No custom code on the board.  The Processing sketch was surprisingly easy to write.  Using this really did feel like using an Etch-a-Sketch.</p>
<p>Here&#8217;s the Hack-a-Sketch in action.  Wait for the big finish where I erase the image&#8230;</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="480" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=7367464&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="640" height="480" src="http://vimeo.com/moogaloop.swf?clip_id=7367464&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>How did I erase the drawing by shaking the computer?  There&#8217;s a mercury switch hidden behind the panel holding the knobs.  When the code senses shaking, the image is slowly erased.  More shaking = more erasure.<br />
<span id="more-12"></span></p>
<div id="attachment_4" class="wp-caption alignnone" style="width: 650px"><img class="size-full wp-image-4" title="disassembled" src="http://nootropicdesign.com/projectlab/wp-content/uploads/2009/11/disassembled.jpg" alt="Disassembled Hack-a-Sketch exposing mercury switch to sense movement." width="640" height="480" /><p class="wp-caption-text">Disassembled Hack-a-Sketch exposing mercury switch to sense movement.</p></div>
<p>Finally, here&#8217;s the Processing code that does all the work:</p>
<pre class="codeblockscroll">import processing.serial.*;

import processing.core.*;
import cc.arduino.Arduino;

PImage backgroundImage;
Arduino arduino;
int STYLUS_X_PIN = 0;
int STYLUS_Y_PIN = 1;
int MERCURY_SWITCH_LEFT_PIN = 8;
int MERCURY_SWITCH_RIGHT_PIN = 9;
// Origin is lower left corner of screen.
int originX = 146;
int originY = 673;
int width = 740;
int height = 530;
int PEN_COLOR = 50;
int GRAY = 217;
int GRAY_ALPHA = 80;
int lastX, lastY;
int SMOOTH_BUFFER_SIZE = 2;
int[] smoothBufferX = new int[SMOOTH_BUFFER_SIZE];
int[] smoothBufferY = new int[SMOOTH_BUFFER_SIZE];
int smoothBufferXSum = 0;
int smoothBufferYSum = 0;
int LEFT = 0;
int RIGHT = 1;
int SHAKE_SPEED_THRESHOLD = 300;
int lastSwitchPosition;
int lastSwitchPositionChange;

void setup() {
    size(1024, 768);
    frameRate(24);
    backgroundImage = loadImage("hackasketch-cropped.jpg");
    background(backgroundImage);

    String[] ports = Arduino.list();
    println(ports[0]);
    println(ports[1]);
    String port = ports[1];
    try {
        arduino = new Arduino(this, port, 115200);
        arduino.pinMode(MERCURY_SWITCH_LEFT_PIN, Arduino.INPUT);
        arduino.pinMode(MERCURY_SWITCH_RIGHT_PIN, Arduino.INPUT);
    } catch (Exception e) {
        println("Failed to find Arduino board");
    }
    stroke(PEN_COLOR);
}

void draw() {
    smooth();
    int x, y;
    if (frameCount == 1) {
        // Give the Arduino some time to initialize so we can get a good first
        // reading from the potentiometers.
        delay(2000);
        lastX = readStylusX();
        lastY = readStylusY();
        for(int i=0;i &lt; SMOOTH_BUFFER_SIZE;i++) {
            smoothBufferX[i] = lastX;
            smoothBufferXSum += lastX;
            smoothBufferY[i] = lastY;
            smoothBufferYSum += lastY;
        }
        point(originX+lastX, originY-lastY);
    }

    x = smoothX(readStylusX());
    y = smoothY(readStylusY());
    if ((x != lastX) || (y != lastY)) {
        line(originX+lastX, originY-lastY, originX+x, originY-y);
    }
    lastX = x;
    lastY = y;

    if (shake()) {
        erase();
    }
}

boolean shake() {
    boolean left = (arduino.digitalRead(MERCURY_SWITCH_LEFT_PIN) == Arduino.HIGH);
    if (left &amp;&amp; (lastSwitchPosition != LEFT)) {
        lastSwitchPosition = LEFT;
        if ((millis() - lastSwitchPositionChange) &lt; SHAKE_SPEED_THRESHOLD) {
            lastSwitchPositionChange = millis();
            return true;
        }
        lastSwitchPositionChange = millis();
    }
    boolean right = (arduino.digitalRead(MERCURY_SWITCH_RIGHT_PIN) == Arduino.HIGH);
    if (right &amp;&amp; (lastSwitchPosition != RIGHT)) {
        lastSwitchPosition = RIGHT;
        if ((millis() - lastSwitchPositionChange) &lt; SHAKE_SPEED_THRESHOLD) {
            lastSwitchPositionChange = millis();
            return true;
        }
        lastSwitchPositionChange = millis();
    }
    return false;
}

void keyPressed() {
    if (key == ' ') {
        erase();
    }
}

void erase() {
    fill(GRAY, GRAY_ALPHA);
    noStroke();
    rect(originX, originY-height, width+1, height+1);
    stroke(PEN_COLOR);
}

// Read current stylus X position relative to the origin.
int readStylusX() {
    int reading = arduino.analogRead(STYLUS_X_PIN);
    return (int)map((float)reading, 0f, 1023f, 0f, (float)width);
}

int smoothX(int v) {
    int index = frameCount % SMOOTH_BUFFER_SIZE;
    smoothBufferXSum -= smoothBufferX[index];
    smoothBufferXSum += v;
    smoothBufferX[index] = v;
    return (int)(smoothBufferXSum / SMOOTH_BUFFER_SIZE);
}

// Read current stylus Y position relative to the origin.
int readStylusY() {
    int reading = arduino.analogRead(STYLUS_Y_PIN);
    return (int)map((float)reading, 0f, 1023f, 0f, (float)height);
}

int smoothY(int v) {
    int index = frameCount % SMOOTH_BUFFER_SIZE;
    smoothBufferYSum -= smoothBufferY[index];
    smoothBufferYSum += v;
    smoothBufferY[index] = v;
    return (int)(smoothBufferYSum / SMOOTH_BUFFER_SIZE);
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://nootropicdesign.com/projectlab/2009/10/31/hack-a-sketch/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>
