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 I 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. 
-----
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.  Also,  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
-----

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 tri-color LED is 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.

www.WhiskeyTangoHotel.Com

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):
-----


Wednesday, July 11, 2012

Repurpose an Old Disk Drive as a Microcontroller Input Device

Every geek either has and old disk drive or soon will. Here is a way to repurpose that disk drive as an input device for a microcontroller project. This example just shows the disk drive blinking an LED. But you get the idea; with some creativity there are many applications. It's so easy it barely qualifies as a hack, but here are the details.
-----
The device that makes a disk drive spin is a DC spindle motor. If you spin the spindle motor a current is produced. Search youtube for LED Stepper flashlight, etc. and you will find many examples of this experiment.

We need to get two of the spindle motor wires on the disk drive ultimately into the microcontroller.  Take the drive apart and make connections to two of the spindle motor wires.  In the pic you see where we soldered small wires to middle spindle motor connection points.  The other end of these two wires are soldered to two of the drives header pins. This makes for a handy way to plug in a JST connector.

-----
Below is a 'scope shot of what the output signal looks like when you spin the spindle motor.  A purist might consider rectifying the output to keep the microcontroller from seeing a negative voltage.  Since the max output is maybe 500mV, I didn't worry about it.
-----
Here is the custom code for the microcontroller; a PICAXE-08M2.  An Analog to Digital Convertor (ADC) input is monitored.  If a signal is detected of the ADC from the spinning disk drive then flash an LED.  Short and simple.

#picaxe08m2
low 2                'LED on output 2.  Make certain it is off
main:                'Start of main program loop
readadc 1, b0   'Read value of ADC on input 1.  Store in b0
if b0 > 1 then   'If there is a signal on the ADC, the disk is spinning so LED on
toggle 2
pause 50
endif
goto main
----
Thanks for the visit!!!
-----
Link back: Hack A Day
-----

Friday, July 6, 2012

Using a MicroController to Train a Cat

Most of the time Kelso is a great cat.  A few examples of his awesomeness can be seen here, here, and here.  However, he still seems to squeeze in some mischief despite a rigorous schedule that includes sleeping 18 hours a day.

For example, we spotted some paw prints on the stove vent hood.  But wait... Kelso is strictly forbidden to even think about getting on the counters so it couldn't have come from him.  Impossible.  Up goes a security camera to gather more evidence:
-----
Busted!  We need a solution and it needs to be high tech.  

A quick search of the spare parts bin at "The Lab" yields a PICAXE 28X1 custom programmable microcontroller, a piezo speaker (that is really really loud!), a Sharp InfraRed Rangefinder, and a AA battery holder.
-----
All of that stuff in the picture is useless as a solution without some simple custom programming.  Basically, we coded the PICAXE 28X1 to continually monitor the Sharp InfraRed Rangefinder to see if Kelso is in front of it.  If he is, blast five LOUD chirps through the piezo speaker then rearm and wait.  The code was easy and straightforward; less that 20 lines.  The only thing special we did was turn off the PICAXE 28X1 brown out detection (disablebod) and slow the internal clock down from 4MHz to 31KHz in an effort to extend battery life.  Here is a pic of the finished rig that will keep Kelso from ever misbehaving again. ;)

-----
And here is demo of the rig in action:


-----
Does it work?  Hell yes it does!!!
Thanks for checking out the build.
-----
Link back: Hack A Day
Link back: Hatched Gadgets
-----

Saturday, June 23, 2012

"Etch a Sketch" Turned Temperature Data Logger

A friend of mine gave me an OKI office printer.  The thing was HUGE and after about five years it finally broke.  Next step, out comes the screwdriver to rescue any useful parts; of which where several stepper motors.  Since what I didn't know about stepper motors was a lot I searched for a "useful" way to learn about them.  I decided to connect two of the stepper motors to an "Etch a Sketch" and ended up with this rig that graphically logs temperature in a strip chart fashion.


Here is a video if you are not interested in the build details and just the want to see the result.  The beer was cold.  The water in the shot glass hot.  Hot makes the graph go up.  Cold makes the graph go down.  When the graph reaches the far right of the "Etch a Sketch" the stylus moves full left and the process repeats.  In the video a temperature measurement is taken (and graphed) every 750 milliseconds, but that can be adjusted to anything; one reading per hour for example. 


-----
The process of driving the steppers was not trivial in the beginning.  First, I had no documentation on these steppers.  The second being I had no idea how "noisy" and power hungry the steppers could be.    The documentation turned out not to be a big deal.  Via the magic of the internet I learned they were of 4-wire, bi-polar configuration.  An ohm meter is all that is needed to figure out the connection scheme. 

----
Close up of one of the OKI printer 4-wire bipolar stepper motors:

-----
Driving a stepper motor requires a microcontroller.  My choice for a microcontroller was the PICAXE 18M2.  
-----
A stepper motor is not like a 'common' DC motor.  You cannot just apply a current and have the stepper spin.  The current has to be applied in sequence across the four available wires.  You also have to control the polarity (direction) of the current.  That said, steppers motors take way more current than a microcontroller can provide.  An H-Bridge motor driver solves the problem by providing more available drive current for the stepper and the ability to switch current drive polarity.

I was familiar with the SN754410NE H-Bridge motor driver.  Plus, I had some in my kit.  So, originally I decided to use one SN754410NE to drive each stepper motor.  This was a mistake that added much frustration.  The stepper motors are incredibly noisy and current hungry.  The noise caused by the steppers and energy from their back EMF (I think) caused nothing to work reliably.  After seeing on a datasheet that L293D motor drivers have protection diodes and some other features, I gave them a try instead.  The L293D is pin compatible with the SN754420NE so the swap was easy.  After inserting the L293D's everything started moving forward as planned with controlling the steppers.


-----
Now that we can control the stepper motors via the PICAXE 18M2 and L293D's we still need to interface then some way to the "Etch a Sketch".  I had a clear plastic cube thats purpose was to protect a trophy baseball.  Since I didn't have a trophy baseball I dismantled the cube and used the two "C" shaped pieces to mount the steppers to with the help of a Dremmel tool and double sided sticky tape.
-----
After mounting the steppers motors, you still have to mechanically couple them to the "Etch a Sketch".  Rubber hose and zip tie wraps worked perfectly.
-----
After getting the mechanicals figured out a "test" pattern was programmed into the PICAXE.  The test worked on the first run so we grabbed the video camera to document the success.


-----
Now that the stepper motors make the "Etch a Sketch" draw, we still need a way to measure temperature.  The PICAXE 18M2 is used to read a DS18B20 sensor (picture below) via I2C bus for this:

-----
To manually position the "Etch a Sketch" stylus, two buttons are wired into the PICAXE 18M2:
-----
After all of that it is just code and software debugging. 

I have other plans for the rig.  Stay tuned!
-----
If you are still with me, here is the build schematic (click to enlarge):
-----

Sunday, June 3, 2012

Swim Heat Counter with PICAXE 08M2

A friend of mine had the exciting job of flipping cards to display heats at his daughter's swim tournament.  Not difficult to do, but it doesn't allow the much mobility for the person assigned to the job.  Wouldn't it be nice to modernize the task and make it wireless?
-----
With a PICAXE 08M2 microcontroller and a few servos the electrical part of the task is pretty simple.   Basically two buttons (a ONES place button and a TENS place button) pull an input to the PICAXE high, causing a subroutine to be called and the appropriate servo to move.  Adding wireless to the rig should be easy as well by re-purposing a cheap remote from a toy RC car to replace the two button/switches that cause the servos to move. 

Adding the mechanical digits will not be completely trivial, by my buddy says he is up to the challenge.
-----
 Short video of the rig in action.
-----
Schematic drawing of the build (click to increase size):
-----
PICAXE 08M2 Project Source Code.  Very simple:

#rem
 *******************************
 ***** www.WhiskyTangoHotel.Com  *****
 *******************************
    Project Name: Walker Swim Heat Counter

    Start Date: June 1, 2012
    
    Program Rev History: 
    This version steps the a ONES digit Servo and a
    TENS digit Servo in ten increments to "display"
    the numbers 00-99.

 ******************************* 
    PICAXE PE Rev: 5.5.1
#endrem

#picaxe08m2 ' using PICAXE 08M2 uC
#COM11 'programming on COM11

'min servopos value = 75
'center servopos value = 150
'max servopos value = 255

symbol Ones_Button = pinc.4 'input button for Ones digit.  Pull high to count
symbol Ones_Position = b0 'servo location var


symbol Tens_Button = pinc.3 'input button of Tens digit.  Pull high to count
symbol Tens_Position = b1 'servo location var

'b2 is variable used for math in calculating both servo positons

'Init some stuff...
let dirsC = %11000111  ' define I/O of PortC.  Not really required.

servo 1,150 ; initialise ones digit servo
servo 2,150 ; initialise tens digit servo
Ones_Position = 0
'Calculate and move Ones digit Servo to "display" 0
b2 = Ones_Position * 15 + 75
servopos 1, b2

Tens_Position = 0
'Calculate and move Tens digit Servo to "display" 0
b2 = Tens_Position * 15 + 75
servopos 2, b2

main: 'main loop continually checks if a button is pushed to move the Servos.
If Ones_Button = 1 then 'move servo for Ones Digit
gosub Change_Ones
endif

If Tens_Button = 1 then 'move servo for Tens Digit
gosub Change_Tens
endif

goto main 'loop and check for button presses


Change_Ones: 'Routine called when "Ones" button is pressed.
If Ones_Position = 9 then 'highest position is '9'.  Wrap to '0'
Ones_Position = 0
else
Ones_Position = Ones_Position + 1
endif
'Convert the Ones_Position into the correct servo location
let b2 = Ones_Position * 15 + 75
Select Case b0
Case 0
servopos 1, b2
Case 1
servopos 1, b2
Case 2
servopos 1, b2
Case 3
servopos 1, b2
Case 4
servopos 1, b2
Case 5
servopos 1, b2
Case 6
servopos 1, b2
Case 7
servopos 1, b2
Case 8
servopos 1, b2
Case 9
servopos 1, b2
endselect
pause 500 'delay 500mSec to allow the servo to move
return ' Change_Ones

Change_Tens: 'Routine called when "Tens" button is pressed.
If Tens_Position = 9 then 'highest position is '9'.  Wrap to '0'
Tens_Position = 0
else
Tens_Position = Tens_Position + 1
endif
'Convert the Tens_Position into the correct servo location
let b2 = Tens_Position * 15 + 75
Select Case b0
Case 0
servopos 2, b2
Case 1
servopos 2, b2
Case 2
servopos 2, b2
Case 3
servopos 2, b2
Case 4
servopos 2, b2
Case 5
servopos 2, b2
Case 6
servopos 2, b2
Case 7
servopos 2, b2
Case 8
servopos 2, b2
Case 9
servopos 2, b2
endselect
pause 500  'delay 500mSec to allow the servo to move
return 'Change_Tens
-----

Friday, May 25, 2012

Progression of a PICAXE LED Chaser (Knight Rider) LED Display

There was a question on the PICAXE forum asking about building up a "Knight Rider" display.  The '80s TV show "Knight Rider" featured a 1982 Pontiac Trans Am named "KITT" that had some blinky lights mounted in the hood that somehow let the car solves crimes and do some other amazing stuff.  Pretty impressive technology for an early '80s American car!

-----
The authentic way to do the "KITT" display is to show LEDs moving back and forth by turning a "main" LED on full bright and surround that full bright LED with progressively dimmer LEDs.  That is not that hard to do using the PWM (Pulse Width Modulation) features of the PICAXE, but I thought there may be an easier way.

I wanted to test a simpler way to simulate the display on "KITT" by just turning the LEDs on/off in sequence quickly.  I was also interested in experimenting with the PICAXE "let dir", "let pins", and "lookup" and this seemed like an easy platform to do this.  In the first attempt a PICAXE 18M2 was used to simulate an eight LED "KITT" display.  The result was surprisingly excellent.  To me, the PWM is not really needed due to the persistence for your vision and the LEDs.  An ADC input on the PICAXE was used to allow for an adjustable delay on how fast the display moves.  Here is a short video of the results:

The original forum question was asked by Jacob2803.  He gave it a try with my code as well and here is a short youtube video of his nice result:  http://www.youtube.com/watch?v=HwoHKqRI-sY
-----
After seeing an eight LED Chaser display the discussion of using more LEDs came up.  More is always better, right?.  The PICAXE forum is an interesting place.  It has participation of users from all levels; beginner to expert, and the brainstorming of solutions (on many problems) can be inspiring.  Many options were provided on increasing the LED count.  My thought on increasing the count on the LED Chaser display was to use the PICAXE 08M2 and the 74154 (4:16 Decoder).  The PICAXE 08M2 has fewer outputs than the 18M2 that was used above, but the 74154 only needs four control signals to turn on any one of 16 LEDs at a time.

Here is a picture and short video of what the 16 LED Chaser looked like on the development board:

-----
The 16 LED Chaser looked so cool, I decided to move it to a PCB and keep it "forever".  It barely looks like it has any similarity to the development board build.  Since the circuit is very minimal it cleans up well on the PCB.
-----
I programmed a few different chaser patterns into the PICAXE that can be selected with a button press.  Here is a short video of the PCB version of the 16 LED Chaser in action.
-----
My code and schematic is below in case you want to build your own.  If you build it and mount it to a 1982 Pontiac Trans Am please send us a pic.  ;)

Schematic:

PICAXE Code:

#rem
 *******************************
 ***** www.WhiskyTangHotel.Com  *****
 *******************************
    Project Name: 16 LED Chaser with 08M2 and 74590 Decoder

    Start Date: May 18, 2012

 *******************************
    PICAXE PE Rev: MacAXEPad 1.3.2
 
#endrem

#picaxe08m2
let dirsC = %11110111
'b0 is used as a general loop counter
Symbol StepDelay = b1
Symbol WhatCase = b2
Symbol MaxCases = b3 'Init value set below.  The # of possible display cases select routines programmed
'w2 (b4 and b5) used in random LED Case Select
Symbol ButtonPush = pinC.3

'Initialize some values
StepDelay = 20  ' Time to keep the only sigle LED the 74590 can turn on until moving to the next LED

Whatcase = 4    'Case Select routine that 'kicks things off' after reset
MaxCases = 4    '# of possible display cases select routines programmed.

main:
if ButtonPush = 1 then 'jump to a different Case Select routine
pause 25
Do While ButtonPush = 1
pause 25
loop
pause 25

if WhatCase = MaxCases then
let WhatCase = 0 ' reset WhatCase if it is equal the # of possible display cases programmed
endif
WhatCase = WhatCase + 1
endif

Select Case WhatCase

Case 1  'LEDs scan up and repeat
gosub LEDsUp

Case 2   'LEDs scan down and repeat
gosub LEDsDown

Case 3 'LEDs scan up the down and repeat.  This simulates the display on the "KITT" car in KnightRider
gosub LEDsUp
gosub LEDsDown

Case 4  'randomly turn on one LED at a time
gosub LEDRandom

end select

goto main

'LED pattern subroutines here.  Of course, more case routines can be added.
LEDsDown:
for b0 = 0 to 7
let pinsC = b0
pause StepDelay
next b0
'jump to 16 to turn on bit position 5
for b0 = 16 to 23
let pinsC = b0
pause StepDelay
next b0
return 'LEDsDown

LEDsUp:
for b0 = 23 to 16 step -1
let pinsC = b0
pause StepDelay
next b0

for b0 = 7 to 0 step -1
let pinsC = b0
pause StepDelay
next b0
return 'LEDsUp

LEDRandom:
RANDOM w2
let pinsC = w2 // 23 + 1 '"//" is modulus divide (returns remainder)
return 'LEDRandom
-----