Das Blinken Lights

Well, I’ve given up (for the time being) on how to use my Macintosh to program the PIC controller. I took my lunch hour today at work to program my PIC p12F675 on the PICKit 1 Flash Starter Kit to blink its lights in a circular fashion. Since there is a lack of good info about this on the web, per my new initiative to inform the world (lol) I’m going to say exactly how I did it.
First, I installed the gnu pic utilities — of which I’m using gpasm to “assemble” my code into pic bytecode. (See below for the code.)
Next I compiled the code like this:

gpasm –dos -pp12F675 –hex-format inhx32 gp2.asm

It is necessary to add the –dos option since the upload program I use is a Windows program. Oh and by the way everything so far is Mac friendly. Now copy the resulting .hex file onto your windows box and upload it using the PICkit(tm) 1 FLASH Starter Kit application. I think I used the “Baseline Flash” instead of the “Classic” version. Control – I Imports, and Control – W writes.
Be sure you have the right kind of PIC — for my program I used a p12f675.

Double click to replay if there is no controller.
Can’t see the video above? Click
here to download our video file, then launch it from your desktop.

Still can’t
see the video? Install Apple’s free QuickTime player.

Here is the code, for those at home who wish to duplicate my experiment.

  1  ;   This file is a basic code template for assembly code generation   *
  2  ;   on the PICmicro PIC12F675. This file contains the basic code      *
  3  ;   building blocks to build upon.                                    *
  4  ;                                                                     *
  5  ;   If interrupts are not used all code presented between the ORG     *
  6  ;   0x004 directive and the label main can be removed. In addition    *
  7  ;   the variable assignments for 'w_temp' and 'status_temp' can       *
  8  ;   be removed. If the internal RC oscillator is not implemented      *
  9  ;   then the first four instructions following the label 'main' can   *
 10  ;   be removed.                                                       *
 11  ;                                                                     *
 12  ;   Refer to the MPASM User's Guide for additional information on     *
 13  ;   features of the assembler (Document DS33014).                     *
 14  ;                                                                     *
 15  ;   Refer to the respective PICmicro data sheet for additional        *
 16  ;   information on the instruction set.                               *
 17  ;                                                                     *
 18  ;**********************************************************************
 19  ;                                                                     *
 20  ;    Filename:      xxx.asm                                           *
 21  ;    Date:                                                            *
 22  ;    File Version:                                                    *
 23  ;                                                                     *
 24  ;    Author:                                                          *
 25  ;    Company:                                                         *
 26  ;                                                                     *
 27  ;                                                                     *
 28  ;**********************************************************************
 29  ;                                                                     *
 30  ;    Files required:                                                  *
 31  ;                                                                     *
 32  ;                                                                     *
 33  ;                                                                     *
 34  ;**********************************************************************
 35  ;                                                                     *
 36  ;    Notes:                                                           *
 37  ;                                                                     *
 38  ;                                                                     *
 39  ;                                                                     *
 40  ;                                                                     *
 41  ;**********************************************************************
 43      list      p=12f675           ; list directive to define processor
 44      #include <>        ; processor specific variable definitions
 46      errorlevel  -302              ; suppress message 302 from list file
 50  ; '__CONFIG' directive is used to embed configuration word within .asm file.
 51  ; The lables following the directive are located in the respective .inc file.
 52  ; See data sheet for additional information on configuration word settings.
 58  w_temp        EQU     0x20        ; variable used for context saving 
 59  status_temp   EQU     0x21        ; variable used for context saving
 60  mcount        EQU     22h
 61  ncount        EQU     23h
 62  new_tris        EQU     24h
 63  new_gpio        EQU     25h
 70  ;**********************************************************************
 71          ORG     0x000             ; processor reset vector
 72          goto    main              ; go to beginning of program
 75  ; (no interrupt)        ORG     0x004             ; interrupt vector location
 76  ; (no interrupt)        movwf   w_temp            ; save off current W register contents
 77  ; (no interrupt)        movf    STATUS,w          ; move status register into W register
 78  ; (no interrupt)        movwf   status_temp       ; save off contents of STATUS register
 79  ; (no interrupt)
 80  ; (no interrupt)
 81  ; (no interrupt); isr code can go here or be located as a call subroutine elsewhere
 82  ; (no interrupt)
 83  ; (no interrupt)
 84  ; (no interrupt)        movf    status_temp,w     ; retrieve copy of STATUS register
 85  ; (no interrupt)        movwf   STATUS            ; restore pre-isr STATUS register contents
 86  ; (no interrupt)        swapf   w_temp,f
 87  ; (no interrupt)        swapf   w_temp,w          ; restore pre-isr W register contents
 88  ; (no interrupt)        retfie                    ; return from interrupt
 91  ; these first 4 instructions are not required if the internal oscillator is not used
 92  main
 93          call    0x3FF             ; retrieve factory calibration value
 94          bsf     STATUS,RP0        ; set file register bank to 1 
 95          movwf   OSCCAL            ; update register with factory cal value 
 96          bcf     STATUS,RP0        ; set file register bank to 0
 99  ; remaining code goes here
101          bcf     STATUS,RP0  ;Bank 0
102          clrf    GPIO        ;Init GPIO
103          movlw   07h         ;Set GP<2:0> to
104          movwf   CMCON       ;digital IO
105          bsf     STATUS,RP0  ;Bank 1
106          clrf    ANSEL       ;Digital I/O
107          movlw   08h         ;Set GP<3:2> as inputs
108          movwf   TRISIO      ;and set GP<5:4,1:0>
109                              ;as outputs
110          bcf     STATUS,RP0  ;Bank 0
112  go
113          ; D0
114          bsf     STATUS,RP0  ;Bank 1
115          movlw   b'11001111'
116          movwf   TRISIO      ;and set GP<5:4,1:0>
117          bcf     STATUS,RP0  ;Bank 0
118          movlw   b'00010000'
119          movwf   GPIO
120          call    delay
121          ; D0
122          bsf     STATUS,RP0  ;Bank 1
123          movlw   b'11001111'
124          movwf   TRISIO      ;and set GP<5:4,1:0>
125          bcf     STATUS,RP0  ;Bank 0
126          movlw   b'00100000'
127          movwf   GPIO
128          call    delay
129          ; D0
130          bsf     STATUS,RP0  ;Bank 1
131          movlw   b'11101011'
132          movwf   TRISIO      ;and set GP<5:4,1:0>
133          bcf     STATUS,RP0  ;Bank 0
134          movlw   b'00010000'
135          movwf   GPIO
136          call    delay
137          ; D0
138          bsf     STATUS,RP0  ;Bank 1
139          movlw   b'11101011'
140          movwf   TRISIO      ;and set GP<5:4,1:0>
141          bcf     STATUS,RP0  ;Bank 0
142          movlw   b'00000100'
143          movwf   GPIO
144          call    delay
145          ; D7
146          bsf     STATUS,RP0  ;Bank 1
147          movlw   b'11111001'
148          movwf   TRISIO      ;and set GP<5:4,1:0>
149          bcf     STATUS,RP0  ;Bank 0
150          movlw   b'00000010'
151          movwf   GPIO
152          call    delay
153          ; D6
154          bsf     STATUS,RP0  ;Bank 1
155          movlw   b'11111001'
156          movwf   TRISIO      ;and set GP<5:4,1:0>
157          bcf     STATUS,RP0  ;Bank 0
158          movlw   b'00000100'
159          movwf   GPIO
160          call    delay
161          ; D5
162          bsf     STATUS,RP0  ;Bank 1
163          movlw   b'11011011'
164          movwf   TRISIO      ;and set GP<5:4,1:0>
165          bcf     STATUS,RP0  ;Bank 0
166          movlw   b'00000100'
167          movwf   GPIO
168          call    delay
169          ; D0
170          bsf     STATUS,RP0  ;Bank 1
171          movlw   b'11011011'
172          movwf   TRISIO      ;and set GP<5:4,1:0>
173          bcf     STATUS,RP0  ;Bank 0
174          movlw   b'00100000'
175          movwf   GPIO
176          call    delay
177         goto go
180  ;delay loop
181  delay   movlw   0x4f
182          movwf   mcount
183  loadn   movlw   0xff
184          movwf   ncount
185  repeat  decfsz  ncount,f
186          goto    repeat
187          decfsz  mcount,f
188          goto    loadn
189          return
191  ; initialize eeprom locations
193          ORG 0x2100
194          DE  0x00, 0x01, 0x02, 0x03
197          END                       ; directive 'end of program'

Oh, were you wondering how I got the nice formatting for the code? I used VIM like this
:runtime! syntax/2html.vim. Do :help 2html in VIM for more info.


PIC microcontroller

I’ve discovered an entirely new realm of geekiness in PIC microcontrollers. These inexpensive ( ~$2.00 ) computers can be programmed to control lights, motors or whatever and can also be controlled through switches or knobs. My mind is exploding with possibilities with what you can make with these. For example, the good old simon says toy, where lights flash in a random sequence which you have to remember, and then you press buttons in the same sequence back. Or a christmas decoration which twinkles. Or lights that zip in a pattern on a billboard sign. Or a robot that drives itself around towards a light source.
Help! I need some ideas of what my first project should be.
I’ve also noticed, as my friend Stacie the librarian preaches, that the internet is indeed a lousy place to find information. Thus as a public service to the world at large, I would like to publicly answer a question that took me about a half hour to figure out. With hope, Google will index this question and answer the future generations of geeks will be spared the pain.

Question: Where do you get GCC 3.1 for Mac OS X (Darwin) version 10.3 or higher?
Answer: It is in a package called gcc3.1.pkg on the XCode 1.5 disk image. You can download XCode from Apple if you set up a free Developer Connection user account.

Well, next I’m trying to use Fink to install libusb so I can build usb_pickit and hopefully get it to work with the PICKit 1 Onboard firmware version is 2.0.2. Apparently the Mac OS tools for the PICKit stopped working when Microchip updated the firmware — doh!



The other day I got into a conversation of movie “pet peeves”. There are a lot of common cliches that Hollywood drags out, some of which just drive me up the wall.
One of these is the computer assisted “hacking” of a numeric access code. Typically the actor will place an electronic safecracking device with a ten digit LCD display on it near the keypad. They turn it on and numbers start whizzing by on the LCD screen. At even increments of time, digits on the LCD screen will stop scrolling — and eventually all ten digits will be “locked” and the security of the system has been compromised.
This special effect gets dragged out any time a “break in” scene that is “high tech” is needed. So you see it in about every other episode of Alias, or in a movie like “War Games”, or what have you. And of course, this would never really work like that.
How does the safecracking device know that it has some of the digits but not all of them right? A well designed security system must never tell you if you have some of the digits right — because this reduces the chances of guessing the combination from ten to the tenth power ( one in ten billion ) to ten TIMES ten ( one in hundred ). So if this security flaw existed, why does the safecracking device bother scrolling so many numbers by??? Surely one hundred is more than enough (and in fact you should be able to guess it in no more than ten tries — just like the game Mastermind).
(as an aside, this type of attack where you are able to tackle each digit independently is how cracking a safe with a dial works. The attacker listens to the tumblers which make a noise when they’re in correct alignment.)
So the security does not exhibit the digit-by-digit flaw, which it most assuredly would not unless they really want ten year old Mastermind players breaking in. In that case, how does the safecracking device know that it has one of the digits? There is no way to know. Furthermore, there is no way to know “how much longer” it will take. Although this is a popular Hollywood suspense builder…

The thug approaches the back of the van, gun raised. Cut to inside the van. Our hero franticly types into the computer..

Hero: (Whispers into phone) Just a few more seconds….

The thug reaches for the door latch on the back of the van and starts to turn it… Cut to inside, a progress bar marked “Time until access code is deciphered: 2 seconds” is on the computer screen…


The best you can hope to know in a “brute force” attack like this is the worst case scenario — if you’ve tried 10% of all the possible combinations and that took you 6 minutes, then at worst you’ll be done within one hour. But you never know if the next combination that you guess will be the right one. I remember once when I forgot the combination to my bike lock that had a three digit combination. It takes a person about twenty minutes to brute force that lock by trying every combination. But if you’re lucky and the combination is 012, you’ll be done much sooner than that.
Oh, and also there is of course no way to know when you have one digit right, so you can’t stop spinning the first dial.
Oh, and don’t you think that the security personelle (or software) would be alarmed by the fact that billions of guesses at the super secret password were being fed into the system?
The real irony in this type of foolishness is that it doesn’t alert people to the *real* security holes in the systems they deal with. And these can be a lot more interesting. For example, it is quite common that a security system is touted to be very secure because it has a 128 digit password. But then later it is realized that a lot of those digits are always the same – thus making it not very secure it all. Or the front door to a system is locked, but the back door is unlocked. Or, security is not applied consistently — have you ever asked someone to email you the password, or told them the password over a cell phone? I’d like to see Hollywood heros exploiting this type of security breach — it could be more interesting and more realistic

Our hero, dressed as a garbage collector, digs through a pile of rubbish.

Hero: (Whispers into phone) I bet it’s in here somewhere

The neighborhood cat looks on with disinterest… Cut to inside the garbage pail, a yellow post-it note is stuck to the side of a plastic cup…

Hero: Ah, here it is — the password is “fKi81A”



Becka got me into this week’s drawing. This week the word was Fiesta and this is what I drew:
(click for full size)


Give me a caption

I drew this picture a few days ago. Can you think of a caption for the picture?


Pitch Black Mountain Dew

If you haven’t read the first entry in about pitch black mountain dew’s blue foam
Well, after much eager anticipation, my analysis about why the bubbles on the weird pitch black mountain dew turn blue is complete. At the end of my previous post, I had a couple of ideas for some experiments to help clarify this issue. I’ve now finished my experiments and am happy to report that I think the mystery is solved!
I was able to collect a sample of the blue foam. This was difficult at first, because it doesn’t turn blue until it’s almost entirely gone. However, I discovered that if I shook the bottle up with the cap closed, and then carefully released some air, the soda would foam up inside the bottle. After a few moments, the foam in the bottle turned blue. Then I released some more air by opening the lid a small amount and collected some of the foam that ran out.
I blotted nine drops of the liquid from the blue foam and nine drops of regular soda onto a paper towel and let it dry for several days. Then I scanned the towel into Photoshop and drew rectangles around each drop and looked at the red and blue values for each
The picture doesn’t really do it justice, the difference is far more startling that that looks. But who am I to trust the human eye to discern differences? This table presents the raw data for the red and blue channels’ average pixel value as well as the ratio of the two, the averages of those six data sets and the p value from the Student’s T Test on the ratios.

regular red regular blue foam red foam blue regular ratio foam ratio
247 213 232 219 1.15962441 1.05936073
248 209 229 224 1.18660287 1.02232143
246 218 231 219 1.12844037 1.05479452
240 210 229 222 1.14285714 1.03153153
248 220 227 220 1.12727273 1.03181818
241 209 228 221 1.15311005 1.03167421
247 217 225 228 1.13824885 0.98684211
240 220 232 221 1.09090909 1.04977376
242 221 225 222 1.09502262 1.01351351
average 244.333333 215.222222 228.666667 221.7777778 1.13578757 1.03129222
std. Dev 3.5 4.99444135 2.6925824 2.818589088 0.03022589 0.02251282
p 3.6661E-05

The T Test comes to the same conclusion as my eye — the colors are different!
The results of a second experiment were negative. When I mixed dish detergent with the soda and whipped it up using my nifty milk frother, the resulting foam bubbles did not turn blue. This suggests that my hypothesis advanced in the first posting about blue dye having the ability to diffuse into bubbles is not correct.
So what does this mean? The conclusion I have come to has to do with a technique known as column chromatography. Column chromatography passes a mixture through a tube that is packed with a material that has an affinity for some of the molecules in the mixture. This will slow the molecules down a little, so as water is washed through the tube the molecules come out the other end at different times. Typically a person will collect a few drops of water into a series of tubes (these are called “fractions”). Then you test each fraction to see what is in it. Using a variety of different columns you can actually purify things pretty well.
Anyhow, I had noticed that the foam only turns blue after the bubbles on top had been bursting for a while. This causes those bubbles near the top to turn back into liquid and flow through the foam underneath. The foam bubbles underneath act like a column, to which the blue dye apparently has a higher affinity than the red dye.
Sorry, I can’t write now – West Wing is starting!


The Pinhole Camera

You may know that I work for a software company that is highly respected for its digital imaging products. As a result, I’ve been trying to learn more about photography. For example,

Near Snail Lake, MN

As it turns out, there is a lot of science in photography. It is much more than I can discuss in a single entry — there is the chemistry of film, optics, exposure, not to mention the artistic concepts such as composition, mood, etc… Besides, I’m not much of an expert yet so I’m not really qualified to discuss most of that (yet!).
So let’s start out by considering the worlds simplest camera, the Pinhole camera. Once we understand that camera and its limitations, we can move on to understand why people use other kinds of cameras most of the time.
A pinhole camera is quite simple. It consists of a box with a large piece of photographic paper mounted at one end, and a very tiny hole that can be covered up at the other end.
A Pinhole Camera

We all know that light moves in a straight line. By using a tiny pinhole, each point on the film only sees a tiny piece of the outside world. I’ve drawn to small grey lines showing how the light from the tree passes through the pinhole to a corresponding point on the film. One incidental result of this is that the image is upside down on the film.
If you make the box longer, the image will get bigger. If you don’t believe me, draw a new pinhole to the right, and trace from the back of the box to see how much of the tree you’ll see on the film. You should see less of the tree — so the image is “zoomed in”. This is one fundamental concept of photography : The longer your focal length, the more zoomed in you are. In fact, when photographers talk about lenses, the talk about the focal length. For a standard camera, a typical lens might have a focal length of 30mm. My friend Jessie’s favorite lens is a 50mm, which is a little bit more zoomed in. A “fish eye” lens might be 15mm. A telephoto lens is in the range of 75 to 300 (or more) mm. 300mm is about a foot, which starts to be a pretty awkward length of lens hang off the front of your camera.
This raises an interesting side question : Why do you need zoom, can’t you just move closer to the subject? For some things that is true, a similar effect can be achieved by moving the camera closer to the subject. But in some cases, the use of zoom provides an important tool in how an image is composed. Consider a scene with a tree and the moon on the corner of the block. You are the photographer, and you stand in the intersection using different focal lengths on your pinhole camera. For this example, I’ll assume that you adjust the position of the camera so that the tree is the same size in each picture.
The same moon and tree picture taken with a very short focal length, medium focal length and long focal length

What you notice is a striking difference in composition. With the very short focal length (e.g. “zoomed all the way out” according to our “focal length / zoom” rule) distant objects (such as the moon) appear very far away. Also, things at the perifery of your vision are more prominent in the picture, such as the street extending away to your right and left. With a very long focal length (e.g. “zoomed all the way in”), distant objects appear larger relative to close objects. Also, objects in the perfery are absent as being “zoomed in” restricts your field of view.
There is a corollary to the “focal length / zoom” rule. As the focal length gets longer, less light makes it to the film. Imagine that the tree is covered with ten christmas lights. If the whole tree is in frame, then ten christmas tree lights worth of light is making it to the film. If you zoom in to show only light, then one tenth as much light is making it to the film. Just because that light looks bigger doesn’t mean that it gets any brighter.
This brings us to the final issue I wanted to talk about: exposure. Exposure means how much light makes it to the film. Exposing film is a chemical reaction, and a specific amount of light is required to make the reaction work. Too much light will make the picture look washed out, or “over exposed”. Too little light will make the picture dark, or “under exposed”. A pinhole camera has four ways to adjust exposure. You can use a shorter focal length to get more light, but at the cost making distant objects look tiny (as discussed above). You can expose the film for a longer length of time (it is not uncommon for pinhole cameras to have exposures lasting minutes or even hours). Long exposures make it hard to take pictures of anything that moves, however. (Early cameras were really little better than pinhole cameras, and took several minutes to expose. This is why pictures from that time are so serious — it is not possible to hold a smile for several minutes without moving, so people held a relaxed pose that they could stay in for several minutes.) You can put a filter in front of the pinhole to reduce the amount of light getting in. You can also alter the chemistry of the film (this is called the ISO of the film) to change how reactive it is to light.
The long exposure time of a pinhole camera is the primary reason that people invented lenses. I’ll save a discussion of lenses for another entry, however.


How Derivative

Once in a while you come across a concept that is so sound and fundamental that it changes your entire outlook on the world. One such concept for me is something I learned in Calculus class fifteen years ago — the Derivative.
The derivative can be explained several ways. One way is to say that it is a measure of the rate of change. For example, interest rates are derivatives. So is inflation. Both of those are the rate of change of money with respect to time.
Another way to think of a derivative is to use a graph. The derivative is the slope of a curve at a particular point. If the curve is like a hillside, then the steepness of the hill at the point you are standing is the derivative. This is also consistent with our first definition, because it is the rate of change of the elevation of the ground with respect to position across.
Once you start looking for derivatives you see them all over the place. Gas milage — rate of miles you travel per gallon of gas. Gas prices — rate of dollars you pay per gallon of gas. Some disciplines are so used to derivatives that they don’t even come out and admit it. Financial people are notorious for this — the term “year over year growth” actually reflects the how much the rate of change of money the company makes per year is increasing. This is a rate of change of a rate of change. “Growth” is normally the rate at which something tangible increases (as in your height), but in financial circles, “growth” means the rate of the rate, or is actually a second order derivative.
(Second order derivatives can be described in several ways. One way that I like– No, this won’t be on the test I’m sharing it just because I like it. One way that I like is to think of a positive second order derivitave as a valley floor. As you hike down it gets less and less steep and eventually you’re heading upwards. A negative second derivative is like a mountain top, as you hike towards it it gets less and less steep and eventually you’re heading down. Some people also say a second derivative is like a smile when it’s positive (start out going down and then go up on the other side) or like a frown when it’s negative.)
I suppose I should come up with a use for a derivative now that I’ve explained it to you. Suppose you wanted to calculate the gas milage of your car. One way would be to create a table and record your odometer reading and how much gas you put in. Then you subtract adjacent odometer readings to see how far the previous tank of gas went. You can then divide the number of miles by how much gas you put in. Finally, average all the values.
Or you could use the Derivative. To do this, simply plot the odometer reading on the Y axis, and the total number of gallons you’ve put in the car on the X axis. Take a ruler and draw a line connecting all the points as best you can. The slope of that line (how many miles the line goes “up” divided how many gallons of gas the line goes “over”) is your gas milage.


Foggy lake

Jesse and I stopped by Lake Johanna on our way to work this morning. The fog was visually stunning:

Fog forms over bodies of water when the atmospheric temperature drops below the water temperature. The vapor pressure of the warm water is greater than the vapor pressure of water vapor in the air. Thus there is a movement of water into the air, which immediately condenses as it mixes and gets cold. Sun “burns off” fog by raising the temperature of the air. As the air temperature increases it’s vapor pressure also increases — which means that it can hold more water.


Rolling a D&D Character

Well, my Dungeons and Dragon’s character, Ollie Oxenfree, was killed over the weekend. A blood golumn got him. We were all very sad.
Anyhow, I got to roll a new character. D&D characters are based on 6 numerical values that are randomly generated by adding together the numbers on three dice. Thus the mimimum score is 3 and the maximum score is 18. There are other ways of getting random numbers between 3 and 18 — for example you could roll a four sided die five times and subtract two. Or you could roll a sixteen sided die and add two. Here is a graph of how likely different rolls are depending on which die/dice you used:

Notice how the more dice you use, the tighter the bell curve appears. You have less than a 1% chance of rolling an 18 (or a 3) and a 12.5% chance of rolling a 10 or 11. For the kind of profession I wanted for my new character (two professions: “Ranger” and “Druid”), I needed at a minimum to roll these scores or higher: 3, 13, 13, 14, 14, 15.
But before I got my hopes up that my character would be able to take on these two professions, I wondered just how likely I was to be able to roll such high scores. I tackled this problem two ways: with a random “monte carlo” simulation, and using statistical analysis.
For the monte carlo simulation, I wrote a perl script that randomly generated scores using a simulated die. It then determined if the rolls met my minimum criteria. After 1000 rolls, it reported the fraction of rolls that were adequate. I had it calculate scores for Ranger+Druid, Ranger only, Druid only, all 3s and all 18s. I know that all 3s or better should be probability of 1 (you always roll a 3 or better). Also, the all 18s should be pretty unlikely (it might not even roll a single one). For those of you following along at home, here is the perl script for this:

@scores = (
[ 3, 13, 13, 14, 14, 15 ],
[ 3, 3, 13, 13, 14, 14 ],
[ 3, 3, 3, 12, 13, 15 ],
[ 3, 3, 3, 3, 3, 3 ],
[ 18, 18, 18, 18, 18, 18 ],
[ 3, 3, 3, 3, 3, 18 ],

foreach $scoresRef (@scores) {
$right = 0;
foreach $i (1..10000) {
my @guess = ();
foreach $b (0..5) {
$guess[$b] = 0;
foreach $a (1..3) {
$guess[$b] += int(1+rand(5.9999999));
@guess = sort(@guess);
my $itsright = 1;
foreach $b (0..5) {
$z = $guess[$b];
if ($z < $$scoresRef[ $b ]) {
$itsright = 0;
$right++ if $itsright;
$total = 1 - ( 1 - $right / 10000 ) ** 6;
print join(", ", @$scoresRef) . " = $total \n";

On Mac OS X, launch, type “perl” and press return. Then copy and paste the code above and press control-D. After a little while it will print out something like this:

3, 13, 13, 14, 14, 15 = 0.0107515164826495
3, 3, 13, 13, 14, 14 = 0.0596604624564983
3, 3, 3, 12, 13, 15 = 0.16341479899658
3, 3, 3, 3, 3, 3 = 1
18, 18, 18, 18, 18, 18 = 0
3, 3, 3, 3, 3, 18 = 0.0214065306042021

Notice the use of the sort function to remove any order issues, also the bit about **6 is because we get 6 tries to roll it right. If we had to roll the scores in the correct order it would be a lot lower probability. What I see is that rolling scores high enough for my ideal character happens about 1% of the time. While this seems pretty unlikely, there are a few things going in my favor. First of all, I get 6 tries to roll (increasing my chances by 6 fold). Furthermore, my montycarlo simulation can easily have some error. Finally, its only 1/2 as likely as rolling an 18 — and I know several of my fellow D&D players have characters with 18s, so shooting for my goal seems perfectly reasonable.
I mentioned that there is a second way to calculate how likely I am to roll my needed scores. The first step will be calculating how likely each sum is. Here is some more perl code for doing that:

foreach $a (1..18) {
$p1[$a] = 0;
$p2[$a] = 0;
$p3[$a] = 0;
foreach $a (1..6) {
$p1[$a] = 1/6;
foreach $a (2..12) {
$p2[$a] = 0;
$start = $a-6;
if ($start < 1) {
$start  = 1;
foreach $b ($start..($a-1)) {
$p2[$a] += $p1[$b]/6;
foreach $a (1..18) {
print "$a : $p2[$a]\n";
foreach $a (3..18) {
$p3[$a] = 0;
$start = $a-6;
if ($start < 2) {
$start  = 2;
foreach $b ($start..($a-1)) {
$p3[$a] += $p2[$b]/6;
$sum = 0;
foreach $a (3..18) {
print "$a : $p3[$a]\n";
$sum += $p3[$a];
print "-" x 32;
print "\n$sum\n\n";

This will print out something like this:

1 : 0
2 : 0.0277777777777778
3 : 0.0555555555555556
4 : 0.0833333333333333
5 : 0.111111111111111
6 : 0.138888888888889
7 : 0.166666666666667
8 : 0.138888888888889
9 : 0.111111111111111
10 : 0.0833333333333333
11 : 0.0555555555555556
12 : 0.0277777777777778
13 : 0
14 : 0
15 : 0
16 : 0
17 : 0
18 : 0
3 : 0.00462962962962963
4 : 0.0138888888888889
5 : 0.0277777777777778
6 : 0.0462962962962963
7 : 0.0694444444444444
8 : 0.0972222222222222
9 : 0.115740740740741
10 : 0.125
11 : 0.125
12 : 0.115740740740741
13 : 0.0972222222222222
14 : 0.0694444444444444
15 : 0.0462962962962963
16 : 0.0277777777777778
17 : 0.0138888888888889
18 : 0.00462962962962963

The first 18 values show the probability that a sum of two dice would be the given value. The second 18 show the values for three dice. Thus rolling three dice and getting a sum of 18 has a P=0.0046. Getting a 10 has P=0.125.
The real complication with calculating the scores for my Ranger/Druid using statistics has to do with figuring out the combinations. Essentially, you need to figure out how likely that *one* of the rolls is 15 or better, but it doesn't matter which. After getting bogged down for quite a while puzzling this out, I decided I would simply trust my monte carlo simulation results 🙂
So I had my dog blow on the dice, and my wife roll them, and sure enough.... I got my scores!