Saturday, May 11, 2013

Speech Synthesis on the Raspberry PI

Here is a quick and simple tip to add speech output to jazz up your Raspberry PI projects.  It is easy as installing the "festival" Text to Speech (TTS) application then calling it from the command line or Python script.

To install "festival" you need to be at a terminal prompt on the Raspberry PI.  Then type:
$ sudo apt-get install festival festival-freebsoft-utils
You will get asked to confirm the install.  Type "Y".

To make the PI talk, just issue a command from the terminal prompt, such as:
$ echo  "Whiskey Tango Hotel dot com Where stupidity meets reality"| festival --tts
That's it.  Of course, you can also execute this from a Python script, etc.

Here's a sample of the output.  Sounds pretty good to me.




Thursday, April 11, 2013

Hand of PI (Twitter controlled Robot Hand)

OBJECTIVE:  Use the Raspberry PI to monitor a Twitter feed and control a mechanical device.

If you are not interested in the details of the build and just want to see the result you can watch the vid below.  

-----
RESULT:  Success!!!  You can control the "The Hand of PI" by sending a tweet to @OurCatDoor.   If  your tweet includes any of the text below, the "Hand of PI" obeys your command.  Valid commands are (lowercase):
  • one (holds up one finger)
  • peace (shows the two finger peace sign)
  • three (three fingers up)
  • hookem (if you are a Texas Longhorn fan this one makes sense)
  • fist (the Hand of PI gets ready to fight)
  • open (ready for a 'high five')
  • finger (well...  this will be the most tweeted command)
Go ahead, try it!!!  Send a tweet command to @OurCatDoor to let us know you were here.
-----
Basically what you are seeing is the Raspberry PI running a Python script searching any tweet sent to @OurCatDoor.  In the video, an iPad sends a tweet to @OurCatDoor that has the command "finger" in it.  It takes a few seconds, but the Raspberry PI finds the tweet, parses it, and find the "finger" command.  The Python script then sets the PI's GPIO ports High/Low.  The PI GPIO is connected to a PICAXE 18M2 (via a HC7404 buffer).  The PICAXE 18M2 reads the PI's GPIO to control five servo motors.  "Hand of PI" reacts with the appropriate gesture.  Watch closely and you can see the text on the screen update as the "finger" command is found and the "Hand of PI" gestures.   There's a lot going on here.  Confused?  This diagram should help (click to see full size):
Of course this isn't full schematic, but it lays out all the I/O to align with the source code you see below.  Really, the interconnects and 5VDC to the servos, PI, PICAXE, and HC7404 is something anyone wanting to duplicate the project should easily understand given the block diagram and source code.
-----
Let's show a few more pics and action videos of the rig before we get into the source code:
 
-----
This video is a bit long but demonstrates all the gestures of the "Hand of PI".  The screen in the background shows output from the Python script.  The screen is not needed, but I included it in the video to show the tweets as they are captured.  Note the "Hand of PI" reacts when a new tweet command is found.
Everyone wants to see the "Hand of PI" flip the bird; that is the last gesture if you want to skip to the end...
----
If you are still with us, enjoy some source code for your reading pleasure.

First the program that is running on the PICAXE 18M2.  It's job is to read the Raspberry PI's GPIO output and control the five servo motors on the "Hand of PI".

' PICAXE 18M2 for RaspPI intergration to Tweeter Controlled Hand Gesture Robot APRIL 2013
'"THE HAND OF PI"
' www.whiskeytangohotel.com
' NOTE: PICAXE Program Editor Rev newer than 5.3.6 causes servo jitter***
' Other than the minium PICAXE 18M2 'keep alive' 22K R & 10K R
' no other R, C, L, etc need for the project.
' Everything on PICAXE powered by 4.5VDC
' The PICAXE drives the servos straight from the chip.
' See pinouts in comments

' 0 is Thumb (PICAXE pin 6)
' 1 is Pointer (PICAXE pin 7)
' 2 is Middle (PICAXE pin 8)
' 3 is Ring (PICAXE pin 9)
' 4 is Pink (PICAXE pin 10)
' Normally Open Button Switch is PICAXE pin 18 (pulled HIGH with 10K)
; this button will not be used for the PI intergration

' PI GPIO 11 connected to c.0 (PICAXE pin 17)
' PI GPIO 13 connected to c.7 (PICAXE pin 16)
' PI GPIO 15 connected to c.6 (PICAXE pin 15)

symbol RaspPI11 = pinc.0
symbol RaspPI13 = pinc.7
symbol RaspPI15 = pinc.6

'Define Servo values to fully EXtend/Open finger
Symbol Ex_Thumb = 60
Symbol Ex_Pointer = 60
Symbol Ex_Middle = 245
Symbol Ex_Ring = 60
Symbol Ex_Pink = 60

'Define Servo values to fully CLose finger
Symbol CL_Thumb = 225
Symbol CL_Pointer = 240
Symbol CL_Middle = 50
Symbol CL_Ring = 240
Symbol CL_Pink = 240

'Init the servos
servo 0, Ex_Thumb
servo 1, Ex_Pointer
servo 2, Ex_Middle
servo 3, Ex_Ring
servo 4, Ex_Pink

pause 400

'Gesture Subroutines are (2^3 = 8 can be PI Callable)
' Valid Tweet commands are: one, peace, three, hookem, fist, finger, wave

'Insure Open_Hand position at program start
gosub Open_Hand
pause 500

main:  'This loops until hell freezes over

'Read the RasPI GPIO bus and  jump to gesture sub routine

If RaspPI15 = 0 and RaspPI13 = 0 and RaspPI11 = 0 then
gosub Open_Hand
end if

If RaspPI15 = 0 and RaspPI13 = 0 and RaspPI11 = 1 then
gosub One
end if

If RaspPI15 = 0 and RaspPI13 = 1 and RaspPI11 = 0 then
gosub Peace
end if

If RaspPI15 = 0 and RaspPI13 = 1 and RaspPI11 = 1 then
gosub Three
end if

If RaspPI15 = 1 and RaspPI13 = 0 and RaspPI11 = 0 then
gosub Hook_em
end if

If RaspPI15 = 1 and RaspPI13 = 0 and RaspPI11 = 1 then
gosub Fist
end if

If RaspPI15 = 1 and RaspPI13 = 1 and RaspPI11 = 0 then
gosub F_You
end if

'If RaspPI15 = 1 and RaspPI13 = 1 and RaspPI11 = 1 then
' gosub Wave  'wave is pretty hard on the servos, so we commented it
'end if

pause 5
goto main

' Gesture Subroutines below:
Open_Hand:
servopos 0, Ex_Thumb
servopos 1, Ex_Pointer
servopos 2, Ex_Middle
servopos 3, Ex_Ring
servopos 4, Ex_Pink
return ' Open_Hand

Hook_em:
servopos 0, CL_Thumb
servopos 1, Ex_Pointer
servopos 2, CL_Middle
servopos 3, CL_Ring
servopos 4, Ex_Pink
return 'Hook_em

F_you:
servopos 0, CL_Thumb
servopos 1, CL_Pointer
servopos 2, Ex_Middle
servopos 3, CL_Ring
servopos 4, CL_Pink
return 'F_you

One:
servopos 0, CL_Thumb
servopos 1, Ex_Pointer
servopos 2, CL_Middle
servopos 3, CL_Ring
servopos 4, CL_Pink
return 'One

Peace:
servopos 0, CL_Thumb
servopos 1, Ex_Pointer
servopos 2, Ex_Middle
servopos 3, CL_Ring
servopos 4, CL_Pink
return 'Two

Three:
servopos 0, CL_Thumb
servopos 1, Ex_Pointer
servopos 2, Ex_Middle
servopos 3, Ex_Ring
servopos 4, CL_Pink
return 'Three

Four:
servopos 0, CL_Thumb
servopos 1, Ex_Pointer
servopos 2, Ex_Middle
servopos 3, Ex_Ring
servopos 4, Ex_Pink
return 'Four

Fist:
servopos 0, CL_Thumb
servopos 1, CL_Pointer
servopos 2, CL_Middle
servopos 3, CL_Ring
servopos 4, CL_Pink
return 'Fist

Wave:  'waves the fingers
servopos 0, CL_Thumb
pause 70
servopos 1, CL_Pointer
pause 70
servopos 2, CL_Middle
pause 70
servopos 3, CL_Ring
pause 70
servopos 4, CL_Pink
pause 70

servopos 0, Ex_Thumb
pause 70
servopos 1, Ex_Pointer
pause 70
servopos 2, Ex_Middle
pause 70
servopos 3, Ex_Ring
pause 70
servopos 4, Ex_Pink
return 'Wave
----
Now for the Python script running on the Raspberry PI.  It's job is to search any tweet sent to @OurCatDoor and parse it for a "Hand of PI" command, then set the PI's GPIO for input to the PICAXE 18M2.



# WhiskeyTangoHotel.com - APRIL 2013   (special thanks to @Rob_Bishop)
# Error traps entered due to json hitting web site that was down etc.
# For next added to end of prog to blink LED to show program is running.

# Import the urllib library to read data from webpages
import urllib

# Import the simplejson library to  decode the data read from the webpage
import simplejson

# Import the time library for delay and lepse time tracking
import time
CurrentTime = time.time()

# Import the Raspberry Pi GPIO libraries
import RPi.GPIO as GPIO

# Set-up the GPIO pins
# Clear the current set-up
GPIO.cleanup()

# Set up the GPIO library to use Raspberry Pi board pin numbers
GPIO.setmode(GPIO.BOARD)

# Set pin 11, 13, 15  on the GPIO header to be an output
GPIO.setup(11,GPIO.OUT)  #PIXACE leg 17 (c.0)
GPIO.setup(13,GPIO.OUT)  #PIXACE leg 16 (c.7)
GPIO.setup(15,GPIO.OUT)  #PICAXE leg 15 (c.6)
GPIO.setup(7,GPIO.OUT)   #Blinkie LED to let us know the prog is running

# Start with Open Hand
GPIO.output(11,GPIO.LOW)
GPIO.output(13,GPIO.LOW)
GPIO.output(15,GPIO.LOW)
Last_gesture = "open"
Error_hit = 0
print "Hand open.  Waiting for Tweet...","\n"

# Function to take Twitter handle (e.g. @Raspberry_Pi) as an argument and return the most recent tweet

# Define the function name and show the arguments
def Latest_Tweet_to_Twitter_Handle(twitter_handle):
try:
# Get the results of a search on Twitter for tweets containing the given hand$
Twitter_search_results = urllib.urlopen("http://search.twitter.com/search.json?q="+twitter_handle)

# Decode the data that we got from the webpage to form a list of tweets
result_list = simplejson.loads(Twitter_search_results.read())

# The function returns the first result in the list
return result_list["results"][0]["text"]
except:
pass

# Main body of the program - Get the latest tweet and check if it contains certain words
# Loop to run forever

#Twitter commands the hand understands are:
#one, two, three, hookem, fist, finger, wave

while(True):
try:
#Time since program start in seconds
DeltaTime = int(time.time() - CurrentTime)

# Function gets the latest tweet mentioning the handle given in next line
Tweet=Latest_Tweet_to_Twitter_Handle("@OurCatDoor")

# START TEST(open): Check if tweet contains the word given in quotation marks
if "open" in Tweet: # and Last_gesture != "open":
Last_gesture = "open"
# If it did contain the word then print out the tweet along with a message
print DeltaTime,"seconds:",Tweet," - Gesture OPEN HAND","\n"
# Turn on the LED
GPIO.output(11,GPIO.LOW)
GPIO.output(13,GPIO.LOW)
GPIO.output(15,GPIO.LOW)
#---END TEST(open)---

# START TEST(one): Check if tweet contains the word given in quotation marks
if "one" in Tweet: # and Last_gesture != "one":
Last_gesture = "one"
# If it did contain the word then print out the tweet along with a message
print DeltaTime,"seconds:",Tweet," - Gesture ONE","\n"
# Set the PICAXE inputs
GPIO.output(11,GPIO.HIGH)
GPIO.output(13,GPIO.LOW)
GPIO.output(15,GPIO.LOW)
#---END TEST(one)---

# START TEST(peace): Check if tweet contains the word given in quotation marks
if "peace" in Tweet: # and Last_gesture != "peace":
Last_gesture = "peace"
# If it did contain the word then print out the tweet along with a message
print DeltaTime,"seconds:",Tweet," - Gesture PEACE","\n"
# Set the PICAXE inputs
GPIO.output(11,GPIO.LOW)
GPIO.output(13,GPIO.HIGH)
GPIO.output(15,GPIO.LOW)
#---END TEST(peace)---

# START TEST(three): Check if tweet contains the word given in quotation mar$
if "three" in Tweet: # and Last_gesture != "three":
Last_gesture = "three"
# If it did contain the word then print out the tweet along with a message
print DeltaTime,"seconds:",Tweet," - Gesture THREE","\n"
# Set the PICAXE inputs
GPIO.output(11,GPIO.HIGH)
GPIO.output(13,GPIO.HIGH)  
GPIO.output(15,GPIO.LOW)
#---END TEST(three)---

# START TEST(hookem): Check if tweet contains the word given in quotation mar$
if "hookem" in Tweet: # and Last_gesture != "hookem":
Last_gesture = "hookem"
# If it did contain the word then print out the tweet along with a message
print DeltaTime,"seconds:",Tweet," - Gesture HOOK EM HORNS","\n"
# Set the PICAXE inputs
GPIO.output(11,GPIO.LOW)
GPIO.output(13,GPIO.LOW)
GPIO.output(15,GPIO.HIGH)
#---END TEST(hookem)---

# START TEST(fist): Check if tweet contains the word given in quotation mar$
if "fist" in Tweet: # and Last_gesture != "fist":
Last_gesture = "fist"
# If it did contain the word then print out the tweet along with a message
print DeltaTime,"seconds:",Tweet," - Gesture FIST","\n"
# Set the PICAXE inputs
GPIO.output(11,GPIO.HIGH)
GPIO.output(13,GPIO.LOW)
GPIO.output(15,GPIO.HIGH)
#---END TEST(fist)---

# START TEST(finger): Check if tweet contains the word given in quotation mar$
if "finger" in Tweet: # and Last_gesture != "finger":
Last_gesture = "finger"
# If it did contain the word then print out the tweet along with a message
print DeltaTime,"seconds:",Tweet," - Gesture FINGER F_YOU","\n"
# TSet the PICAXE inputs
GPIO.output(11,GPIO.LOW)
GPIO.output(13,GPIO.HIGH)
GPIO.output(15,GPIO.HIGH)
#---END TEST(finger)---

# START TEST(wavewave): Check if tweet contains the word given in quotation mar$
if "wavewave" in Tweet: # and Last_gesture != "wave":
Last_gesture = "wavewave"
# If it did contain the word then print out the tweet along with a message
print DeltaTime,"seconds:",Tweet," - Gesture WAVE","\n"
# Set the PICAXE inputs
GPIO.output(11,GPIO.HIGH)
GPIO.output(13,GPIO.HIGH)
GPIO.output(15,GPIO.HIGH)
#---END TEST(wavewave)---

for x in range(0, 10):
# Wait for xx seconds before repeating
# Blinkie LED to let us know the program is running
GPIO.output(7,GPIO.HIGH)
time.sleep(.1)
GPIO.output(7,GPIO.LOW)
time.sleep(1)
except:
pass


-----
If you are still awake, thanks for checking out the build.  Send a tweet to @OurCatDoor to let us know you were here.
-----

Sunday, February 17, 2013

SpiroGraph 3D Laser Project [with Arduino]

Objective:  Reflect a laser beam off mirrors mounted on three fans to display a 'wild' 3D spirograph type pattern on any surface.  Provide fan speed control (manual or automatic) to adjust the displayed patterns.  Full electrical schematic and source code follows.
-----
If you are not interested in the build and just want to see the result, below is a short video.  If you want to really "trip" out you can watch the 20 minute version.  If you turn up the volume you can hear the fans speeds changing.




-----
If you read through the site, you can see I have been using other micro controllers (MSP430, PIC, PICAXE, Freescale Freedom, etc.)  The Arduino platform is certainly one of the most popular and I wanted to give it a try.

I approached this as an Arduino tutorial project because it combines a lot of basics that go into many projects.  I would recommend it to anyone interested in learning the Arduino because:
  • It's cool (maybe even relaxing) to watch.  Be the envy of your friends...
  • The parts are cheap; many probably already in your kit.
  • Demonstrates reading multiple ADC (Analog to Digital) voltage inputs.
  • Demonstrates multiple PWM (Pulse Width Modulation) outputs to vary LED brightness and control motor speeds.
  • Demonstrates random number generation with the Arduino.
  • Demonstrates using arrays for both variables and pin I/O assignments.
  • Demonstrates the Arduino "mapvalue" scaling function.
  • Demonstrates output of Arduino debug values to the PC screen.
  • Demonstrates multiple voltages being used for a project (12VDC, 5VDC, and 3.3VDC).
  • Demonstrates other program control stuff, etc....
If you are trying to learn the Arduino (or really, any other micro controller) this project beats the hell out of just a "Hello World" blinking LED.  The effect is guaranteed to impress your friends at the next Rave Party.
----
For the project you will need a few items:
  • Arduino (I used the Nano pictured above; $9USD shipped)
  • Laser Diode (check eBay for red ones that sell for ~$1.50USD shipped)
  • Three DC fans or motors (I rescued three 24VDC instrument cooling fans)
  • Three small mirrors and double sided tape to attach then to each fan center
  • Three 10K pots (used to control the fan speed independently)
  • Three LEDs and three 330 ohm resistors
  • AC/DC Power adaptor (I rescued an 18VDC wall wart)
  • LM7805 voltage regulator to tame the output from the wall wart to 5VDC
  • L78L33 voltage regulator (provides a 3.3VDC for the laser diode)
  • TC4469 Quad Motor Driver to provide controlled power to the fans
-----
First thing we need to do is arrange the three fan motors in a box pattern.  I fixed them together with yellow zip ties.  The "wall" on the far left is just a fan housing and where we will mount the red laser diode.  There is a better pic of that later.
-----
Here is a pic of the red laser diode mounted on a thick wire.  You can also see one of the small mirrors mounted to one of the fan's center with double sided tape.  
-----
The red laser beam is aimed so that it reflects off each mirror as it spins, and finally, on onto a wall, etc.  The path of the laser on the spinning mirrors is kinda like this:
-----
Next thing you will need to do connect up a bunch of wires per the schematic below.  Since there is voltage on the project that is higher that the Arduino, the LEDs, or the laser can handle pay special attention when connecting the voltage regulators (LM7805 and L78L33) and components or you will "cook" something.  Also, don't try to skimp out and go without the TC4469 to drive the fans.  The Arduino can't source enough current to drive the fans.  Motor drivers are common in projects so this is a good time learn how to use them anyway.   Click on the schematic to make to bigger.
-----
After connecting everything up, the mess will look something like this:
-----
We still need to program the Arduino Nano to control the project; read the POT locations, adjust the fan speeds and LED brightness, speed change delays, etc.  Simply copy and paste the source code below into the Arduino IDE (Integrated Development Enviroment) installed on your PC.  Then download the source code "sketch" into the Nano.  If this step seems daunting check out this page on the official Arduino site.
/*
 **************************************
 ***** www.WhiskeyTangoHotel.Com  *****
 **************************************
 Project Name: Spyrograph Laser (3 axis)

 Start Date:  Feb 2013

 Program Rev History and Notes: 
 Project controls 3 * 24VDC fans (with mirrors attached to the center).  A laser is
 shined onto the mirror.  A '3D' pattern is drawn on the wall with the laser.

 If a control POT is full up, the fans speed is random.
 If a control POT is full down, the fan turns off.
 Else the control POT varies the fan speed manually.

 ***************************************
 */

// Array starts at VAL 0.  PWM outputs for mirror motors on D9, 10, 11
int Mirror[] = {
  9, 10, 11};

// PWM outpts for LED status monitors,  They mimic the fan speed
int Led[] = {
  3, 5, 6};

// Analog pins.  Read Pots that control mirror motors
int Pot[] = {
  1, 2, 3};

int potvalue[3];  // Store the value of the Pot[] (this value will be 0-1023)
int mapvalue[3];  // We take the potvalue and rescale it for PWM outputs

int DelayVal = 2000;      // how fast for the PWM randon speed hold in mSecs
int KnobBuffer = 10;      // how much of the top end or bottom end of the pot to ignore for random or off fan
int FullSpin = 0;         // always 0. We want to hit mirrors with full power at program start
int MaxSpin = 0;          // 0 is full blast. largest val for PWM on mirros during run mode
int MinSpin = 200;        // 255 is off.  lowest speed/PWM for mirrors

void setup()
{
  //Serial.begin(9600);  // Comment in final version, just for debug...

  for (int i = 0; i<=2; i++) { 
    pinMode(Mirror[i], OUTPUT);      // sets the digital pins as output
    pinMode(Mirror[i], OUTPUT);
    pinMode(Mirror[i], OUTPUT);
  }

  for (int i = 0; i<=2; i++) {  
    pinMode(Led[i], OUTPUT);      // sets the digital pins as output
    pinMode(Led[i], OUTPUT);
    pinMode(Led[i], OUTPUT);
  }

  randomSeed(analogRead(0));    // Pin 0 is connected to nothing and will read 'noise' to generate a random seed

  //Spin the fan up full Speed to start and
  //Blink the LEDs as a self test
  for (int i = 0; i<=2; i++) {  
    digitalWrite(Mirror[i],0); // 0 (full low PWM applies full power the the fans)
    digitalWrite(Mirror[i],0);
    digitalWrite(Mirror[i],0);
  }

  for (int i = 0; i <= 50; i++) {  // Blink the LEDs
    digitalWrite(Led[0], 0);       // 0 turns the LED on
    digitalWrite(Led[1], 0);
    digitalWrite(Led[2], 0);
    delay(20);

    digitalWrite(Led[0], 255);     // 1 turns the LED off
    digitalWrite(Led[1], 255);
    digitalWrite(Led[2], 255);
    delay(20);
  } // endSelf Test Loop

}   //end Setup()

void loop()
{
  // Use Array values in a 'for loop' to Read the POTs and control the LEDs and Fans

  for (int i = 0; i<=2; i++) {  
    potvalue[i] = analogRead(Pot[i]);    // read the position of one of the three POTs
    
    //the mapvalue function will rescale the potvalues (0 to 1023) to a range for PWM output (255 to 0)
    mapvalue[i] = map(potvalue[i], 0, 1023, MinSpin, MaxSpin);   // on LOW (0) from the Arduino would turn fan full on due to TC4469 inverted input.

    if (mapvalue[i] <= KnobBuffer) {   // is pot near full up position randomize that mirror speed
      mapvalue[i] = random(MaxSpin, MinSpin);  
      delay(DelayVal);  // if we are random speeding the mirror then delay to allow for the speed adjustment to settle
    }

    if (mapvalue[i] >= MinSpin) {  // if POT is full down then
      mapvalue[i] = 255;           // turn off this fan (255 is off due to TC4469 inverted input.
    }

    analogWrite(Mirror[i],mapvalue[i]);   // Spin the fan to the selected or calulated speed.  0 = full; 255 = off
    analogWrite(Led[i], mapvalue[i]);     // LED brightness mimics fan speed.  0 = bright; 255 = off

    /* Serial.prints below are for debug.  Remove in final version.
    Serial.print(mapvalue[i]);
    Serial.print("   ");
    delay(500);
    */

    } //end control array for loop

    //Serial.println();  //Serial.print for debug.  Remove in final version.

}  // end void()  end of program code
-----
After you clean up all the wiring, the finished goods will tidy up nicely:



-----
If all goes well (which it will after you sort through your wiring errors, etc) you will be rewarded with your own laser light show.  Time to get out that Pink Floyd album and enjoy your work. 




-----
If your still with me, thanks or checking out the build page.  This is a great project because it has a high visual effect; a 'wow' factor.  Good luck.
-----
Link back: Hack A Day
Link back: Hacked Gadgets
-----

Saturday, December 29, 2012

Electric Imp Tweeting Cat Door

Objective:
  • Using the Electric Imp,  create a rig to 'tweet' whenever activity is sensed on a cat door.
  • Create a real time graph of the activity here.
For those not interested in the build details, Kelso helped with this short video of @OurCatDoor in action:
-----
We have two cats (Zena and Kelso) that were eager to get online.  When they are not helping out in the labs (example pic) they like to walk through a cat door and relax on the screened in sun porch where they can enjoy food, drink, and take a bathroom break.

Tweeting cat doors are nothing new to The Net.  However, when I saw the Electric Imp on Sparkfun's weekly product video and thought it could be a different way to tackle the problem and learn a few things along the way.  Let's take you through the process.

To start you are going to need an Electric Imp and an "April" Imp Breakout Board.  Oh, and a cat or two...



The Electric Imp is a pretty cool piece of kit.  It looks like a SD Card, but it is really a Cortex-M3 processor with WiFi on board.  Damn!  An onboard mini USB connector is used only to power the device; not for data.
-----
The Electric Imp is useless until you get it established with a wireless network.  As mentioned above, the USB is not used for data.  So how do you program it?  With light from the screen of an app that is run on your iPhone or Android.  You enter your WiFi SSID (and security paswords if needed) and the app sends "flashes" to the screen that are picked up by the Imp to program it.  The process works surprisingly well.
----
The physical I/O for the project is pretty straight forward.  All that is needed is a magnetic reed switch to sense if the cat door flap has opened.  A blue LED is used as a visual clue for ON/OFF and switch detection.  After deciding how to map the Imp's GPIO for the project, the schematic is embarrassingly simple:
-----
After soldering headers to the April breakout board a connector was repurposed making the connection setup clean and simple.
-----
The real challenge is in the software and the cross platform integration (Imp to WhiskeyTangoHotel.com webserver to Sen.se to Twitter) and that process was not trivial, but I'll take you through that as well.
-----
Now that you have the Imp all wired up and connected to a WiFi network, how do you program it?  Remember again that the USB is just for power.  The Imp is programmed in Squirrel through your browser (I used Chrome) from the Electric Imp website.  To me, Squirrel has a "C" type feel to it.  You work through a screen called "The Planner" to code up your project behind "nodes".  These "nodes" can be connected with "noodles" for flow control.  Here is the Imp planner screenshot of my finished project.  Note that you can't see the source code here as it is embedded under the "blue node".  I'll show my source code below later.
-----
In The Planner above, the Imp runs the code under the BLUE box and passes output to the GREEN box.  The code in the BLUE box has the Imp doing a few basic things:  1) turn on a blue LED to let everyone know the Imp is powered and 2) monitoring a magnetic reed switch on the cat door.  If the cat door is opened the reed switch opens contact.  The Imp will 'see' the switch change and 3) blink the blue LED off to provide a visual confirmation and 4) pass the text string to be "tweeted" to the green box.

So what's in the green box?  When the green box is called a PHP script is executed on the WhiskeyTangoHotel.com webserver.  From this point, we leave the Electric Imp world and enter the Sen.se world.  
-----
Sen.se is one cool place.  Their goal is to assist in internet connectivity of personal devices.  They have widgets, tools, applications, channels and a few other things that I barely understand. One of the widgets found there helps with broadcasting to Twitter.  So, the PHP script in the green box above passes the string the cat wanted to "tweet" to the Sen.se Twitter app and the final result is achieved; a cat walking through a door unknowingly Tweeting a message to the world.  

Presto!  Even without opposable thumbs, the ability to type, speak English, read, or boot a computer our cats are online.  As a bonus, we publicly display a real time graph of the activity here.
-----
A few closing comments... I found the current Electric Imp user community to be pretty small. That said, the project wouldn't have come off without help from Electric Imp forums.  Most notable are "brendandawes" and "Hugo" who were my two main enablers.  Hugo is actually the CEO/Co-Founder of Electric Imp and I was pretty impressed that he is so involved.  That said, I do wonder how the project would have gone with a near cost equivalent Raspberry Pi.  I never really got comfortable with the fact that all my Electric Imp code was not stored locally.  I also wish there were more examples on the web to build a knowledge base from.   But, the Electric Imp package is crazy small and tight with low power draw so that is a huge plus.  In all I can't complain, the project works great and taught me a lot.  I don't have any experience with the Raspberry Pi anyway, so any judgement will have to wait. 
-----
If you are still with us, here is some source code for your reading pleasure:
-----
Code Under the "Blue" Box Electric Imp Planner

/*
Tweeting Cat Door
Dec 2012
www.WhiskeyTangoHotel.Com

Read switch on PIN7 and GND
    Normally Open or Normally Closed can be adjusted in swEvent function
Blue LED PIN9 to V3V is ON if the code in running
    Blinks off for 0.5 secs when door switch dectected
*/

hardware.pin9.write(0); // LED ON, active LOW
local channelOutput = [ OutputPort("Ch 1", "string")]; // String var that gets sent to PHP script

//Watchdog code below send Ping to Imp server every xx secs
//I added this because the Imp was not Tweeting all switch closures and
//power up/down seems to correct it.  Assuming lost cost with Imp server?
function watchdog() {
  imp.wakeup(120,watchdog);  //xxx is seconds between pings
  server.log("WD ping");
}
watchdog();
//End of my watchdog code experiment

// function swEvent handles looking for action on the door switch
function swEvent() {    
        local d = date();  // Date info not sent to twitter.  Used only for planner debug
        local min = d["min"];
        local hour = d["hour"];
        local sec = d["sec"];
        local state = hardware.pin7.read();
        if (state == 0) {   // "1" Tweets when switch opens (for a NC swtich).  "0" Tweets when switch closes (for a NO swtich).
     
        // Select Random Msg.  Increase %xx as number of random msgs increases
            local r = math.rand()%4;   // generate random number (min val is 0.  max val is %xxx in Decimal)
   
            if (r == 3) {
                channelOutput[0].set("Random message for r = 3 here");
            }
         
            if (r == 2) {
                channelOutput[0].set("Random message for r = 2 here");
            }
         
            if (r == 1) {
                channelOutput[0].set("Random message for r = 1 here");
            }
         
            if (r == 0) {
                channelOutput[0].set("Random message for r = 0 here.");
            }
        // end Random Msg selecton
     
        // Blink the LED Off to show a door swing detected
        hardware.pin9.write(1);  // LED OFF
        imp.sleep(0.5)          // 500mS delay
        hardware.pin9.write(0);  //  LED back ON
     
        server.show("r="+r+" @ "+hour+":"+min+":"+sec);  //echo to the Imp Planner status the generated RANDOM# and time.  Used for debug.
        }   // end if state ==0 (or state ==1 depending on NO or NC switch type)
       
        imp.sleep(1.0);  // switch settle time of x.x seconds (keep greater that 0.5)    
        server.log(state);  //  echo switch state (O or 1) to planner window for debug      
}  // End function swEvent

// Configure pin 9 as an open drain output with internal pull up
// Configure pin 7 as switch
hardware.pin9.configure(DIGITAL_OUT_OD_PULLUP);
hardware.pin7.configure(DIGITAL_IN_PULLUP, swEvent);

imp.configure( "TCD w-Blink", [], channelOutput);
------
PHP Script called from Green Box in the Electric Imp Planner:
<?php
$feed_id = "sen.seAsignedXXX.XXXXXX";
$api_key = "sen.seAssignedXXX.XXXXXX";
if(isset($_POST['value'])) {
$data = array("feed_id" => $feed_id, "value" => $_POST['value']);                                                                    
$data_string = json_encode($data);                                                                                   
$ch = curl_init('http://api.sen.se/events/?sense_key='.$api_key);                                                                      
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");                                                                     
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);                                                                  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);                                                                      
curl_setopt($ch, CURLOPT_HTTPHEADER, array(                                                                          
    'Content-Type: application/json',                                                                                
    'Content-Length: ' . strlen($data_string))                                                                       
);                                                                                                                   
$result = curl_exec($ch);
}
?>
-----
Link back: Hack a Day
Link back: Hacked Gadgets
-----

Thursday, December 13, 2012

The BeagleBone

-----
Thanks to Texas Instruments and BeagleBoard a BeagleBone arrived at the doorstep of The Lab yesterday.  The BeagleBone is an extremely cool piece of kit that is basically a credit card sized Linux computer.  It uses a TI Sitara ARM Cortex processor with plenty of I/O.  The on board SD card comes preloaded with the OS and after a short five minutes (using the included USB cable) I had the BeagleBone establish a connection with my Mac and observed the "all is Okay" heart beat pattern on one of the user LEDs.

I'm pretty excited about the BeagleBone; it seems crazy powerful, and plan to use it to establish world domination.  Stay tuned!
-----

Sunday, November 18, 2012

Analog Clock turned DC Voltmeter

Why create, what could be, the most impractical way to measure a DC voltage?  Well, because "Measurement Matters".

Actually, the idea was given to me in the comment section of my Voltmeter Clock project which was featured by the awesome team at "Hack A Day".  That is where rue_mohr wrote the comment, "who can be the first to turn a clock into a volt meter?"  Well, that is (and remains) the stupidest ideal I ever heard.  Now, read on....
----
The concept is easy.  Use the "time" on an analog clock to display measured voltage values between 0-12VDC.  1 o'clock means 1VDC, 2 o'clock means 2VDC; if the time reads 10:30 that means 10.5VDC, etc.   To do this a stepper motor is connected to the adjustment knob of the analog clock.  This short video of the rig being tested should help make things clear:
---
One of the ADC inputs on a PICAXE 18M2 microcontroller is used to read/digitize the voltage to be measured.  After the PICAXE measures the voltage, it gets translated into the number of steps the stepper motor needs to move.  This stepper motor movement adjusts the clock to display the voltage that was measured.  The PICAXE doesn't have enough output current to directly drive a stepper motor so the PICAXE feeds a L293D Motor Driver IC.  The outputs of the L293D are then used drive the stepper motor.

Since the clock can display a maximum value of "12 o'clock", the rig was designed to measure a maximum 12VDC input signal.  However, the max input voltage for the ADC on the PICAXE 18M2 is about 5VDC.  To tame the input signal for the PICAXE a simple 3:1 voltage divider (10K, 10K, 10K) was implemented.  This limited the input voltage into the PICAXE to 4VDC.  A trim pot was also used to adjust for the input impedance of the PICAXE and to help calibrate the measurement results.
----
Here is a video of the rig in action side by side with a DVM.
---
All in all the rig works as designed but has terrible lag and is no way what anybody would consider NIST traceable.  The accuracy is estimated at ~100mV.  The two control buttons pictured below help by allowing manual calibration of the rig to 0VDC (12 o'clock position).
---
I can't imagine that this project will ever be duplicated, but as always I will send schematics and source code to those that request it.  If you're still with us, thanks for checking out our site.
-----
Link back: Hack A Day
Link back: Hacked Gadgets
-----



Saturday, September 29, 2012

FRDM-KL25Z Demo: Freescale Development Platform


We put an early pre-order in with ELEMENT14 for Freescale's Kinetis KL25Z development board and it arrived this week.  The dev board has a very solid feel and cost only $12.95.  A great value when you consider all the features; including a Freescale MMA8451Q 3-axis accelerometer glued right onto the board!  Freescale's description on the dev board is "The Freescale Freedom development platform is a low-cost evaluation and development platform featuring Freescale's newest ARM® Cortex™-M0+ based Kinetis KL25Z MCUs."
-----
Here is a short video demonstrating the MMA8451Q in action.  The code has a tri-color LED White when flat; Red when tilted up; Blue when tilted sideways:
-----
The kit comes with headers, a quick start guide, and has the following high level feature set:
- KL25128VLK4 - Cortex micro controller with:
     128Kb FLASH, 16Kb SRAM
     48MHz operation
     Full speed USB controller
     OpenSDA USB debug interface
     Tri-color LED
     Capacitive touch slider
     Reset button
     Expansion IO accepts Arduino form factor shields
-----
More fun to come.  Stay tuned.
-----

Wednesday, August 29, 2012

Four Letter Word Clock via uC

Why build a clock that displays four letter words?  The current time is everywhere; on your PC, smartphone, GPS, MP3 player, etc.  Heck, you may even own a watch!  Four letter words are pretty common as well.
-----
So why then?
     1st)  I had this display that I bought from DealExtreme.Com.  The only reason I got it was because it was so cheap.

     2nd) I wanted to experiment with writing/reading data from an EEPROM with a microcontroller.

     3rd) I wanted to experiment with controlling two devices on the I2C bus in one application.

But.... I wanted a fun project idea to make the effort seem somewhat worthwhile and settled on a Four Letter Word Clock.

If you you just want to see the results and are not interested in the build details, here is a short video demo.

The time is shown in 24 hour format on the left four 7-segments.  Every second a different four letter word is shown on the right four 7-segments.  The eight LEDs under the 7-segments progress from left to right as a way to display seconds.  If you listen closely to the video and you can hear a relay that gives the clock a mechanical ticking sound. 

 The buttons under the LEDs are used to set hours (S1), minutes (S2), increase display brightness (S6), decrease display brightness (S7), and turn ON/OFF the mechanical ticking sound (S8) from the relay.

The major components of the build are (full schematic to follow):
     - Eight x 7-Segment + 8 x Red/Green LED + 8 x Input Button Display Module
     - 24LC256 EEPROM to store the 1,003 four letter words
     - DS1307 Real Time Clock (RTC) for time keeping
     - Small relay to provide a clock like, mechanical ticking sound
     - PICAXE 18M2 microcontroller with custom code provides the brains
------

The display from DealExtreme.Com is pretty awesome for the price.  It contains eight 7-segment LED displays, eight LEDs that can be red, green, or red/green, and eight button switches.  The display has a solid, well built feel to it and was a bargain at $4.99.  As a plus, you can control all these feature with only three I/O pins on a microcontroller.  On the downside, it ships with no documentation (zero, zip, nada...) so plan on doing some web searching to understand it.
-----

The 24LC256 EEPROM, DS1307 RTC, and PICAXE 18M2 are easy to get from many web sources.  I rescued the Teladyne 712-5 relay from a trash bound PCB.  A good thing because a web search shows that relay at $28 (it's an RF spec relay!).  No fear, you can leave the relay off or just use any cheap relay as it is not used to switch any current, just for the ticking sound.
-----
Now came the time to load the 24LC256 EEPROM with four letter words.  So... to the internet for a quickie download of all the four letter English words (including all your favorite cuss words) in one tight ASCII text file.  Unfortunately, 7-segment displays don't display letters like "K", "M", "V", "W", "X", and "Z" very readable.  I wrote a short Python script to pull out the offenders, which also meant some of the more 'expressive' words where lost.  After it was all done, there were 1,003 four letters words that easily fit into the 24LC256 EEPROM.  A short (and separate) program was written to tell the PICAXE 18M2 to load these words into the 24LC256 EEPROM.
-----
The harder part was the code to drive the display.  The lack of documentation made it pretty challenging.  I always find the PICAXE forum helpful in these situations (special thanks to "mjy58").  After much coding/debugging, the problem was solved. 

Controlling the two I2C devices (the 24LC256 EEPROM and the DS1307 RTC) from the PICAXE 18M2 was a bit easier than I expected after sorting through the addressing procedures.
----
Here is a short vid (time lapse) of the rig working on the AXE091 development board.  In the vid you can see the eight red LEDs progress from left to right as the seconds tick by.


-----
After verifying the operation for a few days the whole mess was moved off the AXE091 development board and onto a strip board PCB.  Installing the rig into a $3.49 metal project box from Radio Shack provided a clean finished product.
 -----
Below is the build schematic (click to enlarge).  

I will provide my source code on request.
-----
Link back: Hack A Day
-----

Monday, July 16, 2012

ZIF Socket Allows Programming of PICAXE Family

Lately I have been programming several PICAXEs for people due to my motorcycle gear position indicator project. It is a bit of a pain to insert and remove a PICAXE from my AXE091 dev board just to program a PICAXE. Plus, I often have a PICAXE already pushed into the dev board. Removing it with all the surrounding wires is not easy and depending on the state of the current project it could be harmful to the poor PICAXE I'm trying to program.  Basically, I needed a simple way to plug in a PICAXE and download code to it.  My solution: 
-----
You can see from the diagram in the picture, you plug the PICAXE microcontroller into the ZIF socket one way to program PICAXE-08/14 family devices. To program the PICAXE-18 family place the notch and pin 1 to the opposite side of the ZIF socket. The rig tests fine with all the PICAXE families mentioned.  
-----
I did solder female header rails adjacent to both sides of the ZIF to allow easy hook up of a servo, LED, etc.  However the point of the design was to create an small, tight, easy way to download code into a PICAXE and not create a development board.
-----
The cost was close to "free" since I already had a ZIF socket.  Labeled schematic follows (click to enlarge):
-----