Thursday, February 28, 2008

Weight Loss Milestones: Past, Present and Future

Past

My time-weighted, moving-average BMI dropped below 30 on the 7th. Also, I had to buy a couple new pairs of pants several months ago.

Present

The new pants are starting to feel a little loose too. And just this morning, I put my belt down another notch. To the last notch. It's a little bit too tight this way, but up a notch is way too loose. "Pants feel a little tight" is a good way to keep from snacking at work.

Future

Looking at my log, I see that it will be a year on March 26. I've dropped 33 lb in that time. Since I need a short-term goal to really get me moving, I thought maybe I'd try to reach 40 lb (2/3 of my original long term goal) by the 25th, but I don't think that's really feasible.

Up until now, I've been short an average of ~350 calories/day. To lose 7 lb in 30 days I'd have to short myself ~800 calories/day. That doesn't sound too healthy. So I don't know what short term goal I can set myself.

Wednesday, February 13, 2008

Charlieplexing

A few weeks ago I was really proud of myself for figuring out how to make a binary clock with multiplexed outputs to save pins. Now I learn about charlieplexing and I'm agog. Simply agog.

One project I've been kind of wanting to make is an LED cube. To illustrate just how awesome charlieplexing is, look at how many output pins you'd need to drive an LED cube of a given size compared to the simple multiplexing I "invented".

Edge Length# LEDsReq. Multiplexed OutputsReq. Charlieplexed Outputs
327126
464209
51253012
62164216

So on the Arduino, where I think I have 12 ports to work with, I could either do a 3x3x3 cube the old and busted way or do a 5x5x5 cube the new hotness way. (Or maybe I have 18-19 ports, in which case it's still 3x3x3 the old way but now 6x6x6 the new way.) But how can you possibly control that many LEDs with so few ports? Read the instructable!

Or read this simplified summary: Basically, you set things up so that every port can be either positive or negative. Then attach your LEDs so that every possible combination of ports lights one up. (Remember that LEDs are one-way valves, so port A being positive with B negative can light one LED while reversing polarity can light another one. Just remember not to cross the streams.) "Every possible combination" of N ports is N *(N - 1), so with, say, 9 ports you can control 9 * 8 = 72 LEDs.

5x5x5 isn't enough to be a 3D display, though. But a larger cube could be decomposed into smaller cubes each controlled by a separate microcontroller. 10x10x10 is probably large enough to show some cool animation, although coordinating 8 microcontrollers might be a pain. Not to mention wiring up 1000 LEDs.

Wednesday, January 23, 2008

The Parable of the Parallel Parabola

OK, so....man, I wish I'd been detailing every little step so I wouldn't have to regurgitate it all up in a huge mass. I'll try to make this short.

First of all, I used my calculation to make a simple parabolic reflector. I just plotted it out on graph paper and then set a few nails as guides to hold the mirror in place. This actually worked really well. (Even more surprising in light of how poorly the (first!) oven-formed one came out. More about which below.)

The one on the right has a black dot where I pre-calculated the focus to be, the one on the left is just a different focal length.

Now then. Having a single strip mounted with nails isn't that useful to me, so I want to mass produce these. Can't use the nail thing as a form since it'll just bend unevenly. I spent quite a few days trying to figure out how to make a jig that would cut a perfect parabola, but it was too hard (I still have some ideas on that, though, but that's another 2 or 3 posts). (And before you tell me, I know all about the T-square and string method of drawing one.) I eventually decided to just freehand follow a line.

So I had my shop assistant cut a parabola for me and I sandwiched the mirror in there. (My shop assistant is my father-in-law down the street who actually owns a bandsaw.)

(Other item of note: I originally wanted to have the mirror soften and sink down into shape, but that creates alignment problems. Instead I clamped the bendy strip cold. But that means it's hard to tell when I've reached temperature. So I put a probe down into the coldest part of the thing. The tip of the temperature probe is resting right on the mirror, so when that gets up to ~210°F, I can stick a fork in it. This takes like 2 hours--wood is a really great insulator, unfortunately.)

(Oh also: You can't see it, but there's a little alignment peg sticking out of the convex part of the form. There's a corresponding hole in the concave part so it can stick through. There's also a hole in the middle of each mirror. If I put each mirror on the peg, then after I'm done with all of them, I can line them up perfectly. So clev.)

The result: Not so great.

How could that possibly be? How could a few nails hastily thrown together at a few points make a better parabola than a careful, full-contact form?

Then a phrase floated up out of the darkness1. The curve parallel to a parabola is not another parabola. Just think about that for a minute. If you have a parabola and you want to make a curve parallel to it, you can't just take the same parabola and shift it up. Nor can you use some other parabola. (Read the gories yourself, it's pretty cool. If you like that sort of thing.)

So if you cut a parabolic form and sandwich it around a mirror, FOR EXAMPLE, then you are probably going to get the wrong shape because the two halves want to be parallel (i.e. separated by the thickness of the mirror) but can't. Wellity wellity wellity.

I took the equations in that paper and made a little program2 that would generate an SVG file of the shapes I wanted. Now I can take those back to my shop assistant and have him cut it out again.

(Note to anyone who actually reads this far, runs the program, examines the output and starts wondering: The curves aren't really all that different. I think the issue isn't so much that the curve is wrong, but that the poor alignment doesn't provide even pressure across the entire mirror. So it ends up wibbly-wobbly rather than smooth. Then again, the freehand wood parabola isn't all that smooth either, so maybe THAT'S the source of the error. The nail method at least creates a smooth curve, even if it isn't mathematically perfect.)

1I think it came from Practical Conic Sections, a really rip-roaring tale that I've been reading to the kids at bedtime. But seriously, it's very clear and pretty practical.

2

#!/usr/bin/python

# p1 and p2 are parallel to the parabola, i.e. a constant distance
# away *along the normal to the parabola*.

# For a curve C with generated by the function y = f(x), the parallel
# curve C' is given parametrically by:

#                 y'
# X = x - k -------------
#           sqrt(1+(y')^2)
#
#                 1
# Y = y + k -------------
#           sqrt(1+(y')^2)

# where k is the distance of the parallel from the curve.

# For derivation, see "The Curve Parallel to a Parabola is not a
# Parabola" by F. Max Stein.

import math

print '<?xml version="1.0" standalone="no"?>'
print '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"'
print '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'
print '<svg xmlns="http://www.w3.org/2000/svg"'
print '    width="8.5in" height="14in">'

focallength = 2.5
a = 1/(4.0 * focallength)
mirrorwidth = .125

vertoffset = 7
horizoffset = 2
phorizoffset = 2
prevx = 0
prevy = 0
pprevx = 0
pprevy = 0
first = True
x = -5.5
while x <= 5.5:
    y = a*x*x
    px = x - (mirrorwidth * 2 * a * x)/(math.sqrt(1 + (2*a*x)**2))
    py = y + (mirrorwidth * 1)/(math.sqrt(1 + (2*a*x)**2))
    if not first:
        print '<line x1="%.2fin" y1="%.2fin" x2="%.2fin" y2="%.2fin" style="stroke:black;stroke-width:2"/>' \
              % (prevy+horizoffset, prevx+vertoffset, y+horizoffset,x+vertoffset)
        print '<line x1="%.2fin" y1="%.2fin" x2="%.2fin" y2="%.2fin" style="stroke:red;stroke-width:2"/>' \
              % (pprevy+phorizoffset, pprevx+vertoffset, py+phorizoffset,px+vertoffset)
    prevx = x
    prevy = y
    pprevx = px
    pprevy = py
    x += .125
    first = False

print '</svg>'

Friday, January 11, 2008

Parabolae Foci

I keep having to solve this problem. It's not hard, but to "save time" I usually google it and find too much information and not enough explanation. Then I end up solving it myself. And it's so easy that each time I figure it out I'm like "there's no need to write this down--it's obvious BY INSPECTION". And then I forget it. So here it is:

Where is the focus of a parabola? Alternatively, what formula should I use to create a parabola with a given focus?

Take the equation y = ax2. Obviously the focus will be on the y-axis, but how far up? We know all the incoming rays will meet there, so let's choose a convenient one. A great choice is a ray that is turned by 90°. That is, it comes in vertically, hits the parabola, and heads towards the focus horizontally.

Since the angle of incidence equals the angle of reflection, the slope of the parabola at the point the ray hits is going to be 45°. (I spent like 20 minutes using gnuplot and the gimp trying to illustrate this before giving up. Just visualize it.) Where on a parabola is the slope 45°? Slope is also rise/run, so the the slope in the y = mx + b sense is 1. Where is the slope 1?

The equation was y = ax2. The instantaneous slope is the derivative, y' = 2ax. We want that to be 1.

2ax = 1
x = 1/2a

Substitute in to find out where on the y-axis this is.

y = ax2
y = a(1/2a)2
y = 1/4a

Now let's say I want to make a parabola with a focus that is 6 inches from the bottom of the curve.

1/4a = 6 inches
a = 1/24 inches

Therefore my equation in inches should be: y = .0416x2. (I think. Contradicting my claim about how easy this is is the fact that I actually got this wrong on paper, TWICE, before posting this.)

Monday, January 7, 2008

SUCCESS!

A non-blurry, curved mirror.

In my last post, I hypothesized the problem might be too much time spent in the oven, causing some kind of degradation. That prompted epicanis to wonder if the acrylic was oxidizing. That in turn made me actually take a close look at the failed samples (why I didn't already do this is a mystery).

The acrylic is actually fine in those failures. It's the mirror backing that cheesed out on me. What is the backing made of? Who knows! What do I do about it? I dunno!

Then I was coincidentally reading a book about polymer clay and it had a tip for firing: Put it in at a sub-firing temperature to evenly heat the item, then turn it up to actually harden it. And I was all: whoa. I know that the softening point for acrylic is around 230°F, but I've had to turn the oven up to 250°F to get the samples to bend. I've been chalking it up to oven imprecision and chemical composition variation. But I think the real issue is that the core of the mirror doesn't get hot enough until the outside is too hot.

So this time I put the whole apparatus (which I should have taken a pic of, sorry) inside the oven at 200°F until a probe told me it was more or less up to temp. Then I just cranked it up to 215°F and voila, it worked.

Now I need to do a bunch of these at once (or one large sheet)...

Wednesday, January 2, 2008

Your Favorite Geek Desk Toy Sucks

I've seen these binary clocks around the office. They are fairly cool, but they fail to please in one important way: Each decimal digit is represented separately. 14 seconds is represented as a binary 1 and a binary 4, rather than a binary 14. Granted, reading 6 bits depicting 0-59 seconds is a little harder than the 4 bits required for 0-9. But is ease of use really the primary concern of a binary clock?

MISSION: Build this clock the right way. Namely, 6 bits for the seconds, 6 bits for the minutes and 5 bits for the hour (or maybe 4 bits for the hour with 1 bit for AM/PM). (Another idea would be a straight-up 17 bits for the 86400 seconds in a day, but seriously.)

Now then. I know there are clock chips out there. And it is probably possible to do this using hardware only, say with a 555. But I'm a dumb programmer, so everything looks like a Turing-complete problem to me. Plus I already have an Arduino. So that's the medium of choice. Using an Arduino, some LEDs and resistors and pure force of will, I'm going to make this work.

But there's a problem already. My design calls for 17 LEDs. The Arduino only has 14 output ports1, 2 of which I can't use because they are special. The solution to this problem is multiplexing. The basic idea is that you use X/Y coordinates to address each LED, Battleship-style. So for MxN LEDs, you only need M+N ports.

Let's say I want to light up the LED labeled 0,0. I need to apply positive voltage to A (the left column) and negative to 1 (the bottom row). B and C should be low while 1 and 2 should be high to "push the wrong way" against the remaining diodes.

But now there's another problem. Let's say I want to light up both 0,0 and 2,2. I apply positive to A and C and negative to 1 and 3...and I get all four corners lit up. Long story short, it is also necessary to employ a spot of subterfuge. If I want 0,0 and 2,2 lit up, I have to do them one at a time, but switch back and forth so fast nobody's the wiser.

And finally, there's the little matter of the clock function itself. There isn't an API call for that exactly, but the underlying chip supports interrupts. I basically just copyandpasted the timer code from elsewhere and then added a long comment explaining it to myself, probably incorrectly.

Grainy video (the ticking is an amazingly coincidental loud clock in the same room):

Somewhat less grainy still shot:

The code:

#include <avr/interrupt.h>
#include <avr/io.h>

#define NUMPOS 6
#define NUMNEG 3

int pos[NUMPOS] = {9,8,7,6,5,4};
int neg[NUMNEG] = {12,11,10};

int i = 0;
int j = 0;
int k = 0;
int lastpos = 0;
int lastneg = 0;

int isr_counter = 0;
int oldsecond = 0;
volatile int second = 0;
int seconds = 0;
int minutes = 31;
int hours = 13;

/*  
   Here's how I think this works.  The Atmega168 clock runs at 16MHz.  
   The "prescaler" divides that down.  In this case, it clicks at 2MHz.  
   Each time it clicks, it increments at 8 bit register by 1.  The register
   overflows after 256 clicks.  That overflow is the interrupt we receive.

   2000000 clicks/second divided by 256 clicks/overflow = 7812.5 overflows/second.
   So if I could count 7812.5 overflows, I know a second has elapsed.  I can't
   find .5 of an overflow, so I should really use the /4 prescaler.  But 
   a) that uses more power and b) I can't figure out what bits to set to do that.  
*/

ISR(TIMER2_OVF_vect) {
  isr_counter++;
  if (isr_counter > 7811) {
    second++;
    isr_counter = 0;
  }
};  

void SetupTimer2(){
  //Timer2 Settings: Timer Prescaler /8, mode 0
  //Timer clock = 16MHz/8 = 2Mhz or 0.5us
  //The /8 prescale gives us a good range to work with
  //so we just hard code this for now.
  TCCR2A = 0;
  TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20;

  //Timer2 Overflow Interrupt Enable
  TIMSK2 = 1<<TOIE2;

  //load the timer
  TCNT2=0;
}

void setup() {
  for(i = 0; i<NUMPOS; i++) {
    pinMode(pos[i], OUTPUT);
  }
  for(i = 0; i<NUMNEG; i++) {
    pinMode(neg[i], OUTPUT);
  }

  for(i = 0; i<NUMPOS; i++) {
    digitalWrite(pos[i],LOW);
  }
  for(i = 0; i<NUMNEG; i++) {
    digitalWrite(neg[i],HIGH);
  }
  
  Serial.begin(9600);
  SetupTimer2();
}

void showXY(int col, int row) {
  digitalWrite(pos[lastpos],LOW);
  digitalWrite(neg[lastneg],HIGH);

  digitalWrite(pos[row],HIGH);
  digitalWrite(neg[col],LOW);
  
  lastpos = row;
  lastneg = col;
}

void loop() {
  // time changed, so readjust all the details
  if (oldsecond != second) {
    if (second > 59) {
      second = 0;
      minutes++;
      if (minutes > 59) {
        minutes = 0;
        hours++;
        if (hours > 23) {
         hours = 0;
        }
      }
    }          
    seconds = second;
    oldsecond = second;
  }

  // seconds is column 2 and has 6 bits
  k = 2;
  for(j=0; j<6; j++) {
    if (seconds >> j & 1) {
      showXY(k,j);
    }
  }

  // minutes is column 1 and has 6 bits
  k = 1;
  for(j=0; j<6; j++) {
    if (minutes >> j & 1) {
      showXY(k,j);
    }
  }

  // hours is column 0 and has 5 bits
  k = 0;
  for(j=0; j<5; j++) {
    if (hours >> j & 1) {
      showXY(k,j);
    }
  }

}
1Possibly not true. I found one post that said the 6 analog in ports could be used as digital out. But even if multiplexing isn't strictly necessary for this project, it would be for a larger one.

Friday, December 28, 2007

Acrylic Mirror Failures Learning Opportunities

The acrylic mirror samples arrived. I got 3 mirrors about the size of a credit card, but thicker, like a piece of glass.

OBJECTIVE: Create a "trough mirror" that focuses onto a line.

KEY FACT #1: Acrylic mirror softens and bends at around 230-250°F.

KEY FACT #2: A parabola is a mathematically perfect focusing shape, but (a small section of) a circle is plenty fine for my needs.

FIRST ATTEMPT:

I got a big, glass jar with smooth sides. I put it lying down inside the oven. I balanced the mirror on top, shiny side pointing down (and with the protective plastic sheet still on it). I had to tape the mirror in place.

Starting at around 215°F, I slowly heated the oven up until the mirror ends started drooping. After probably an hour of watching it slooooooowly bend, I just reached in with an oven mitt and press-formed it to the glass.

RESULT: Meh. The shape is great and the focusing is accurate but the mirror got all foggy. It looks more like polished metal now. Also the spots where the tape was touching are distorted.

SECOND ATTEMPT:

My theory was that I should have the mirror pointing up, which might make the cloudiness go away and would make using tape unnecessary.

This time I used a regular soup pan tipped on its side. I put the mirror inside so it could form to the inside curve of the pan. Left the protective plastic on. Set the oven to 250°F (that's what I had worked up to from the first attempt) and waited. And waited. And waited.

Once again, I eventually just reached in and press formed it. When I removed the sheet....still cloudy.

THIRD ATTEMPT:

I watched the video again. Oh, I'm supposed to remove the protective plastic. Replay the second attempt, but this time remove the thing first.

After waiting the requisite Long Time, I could see the mirror was already foggy even before I press forming it. Aha! Not the plastic or the form!

WHAT'S PROBABLY GOING ON:

I have small samples, so gravity isn't enough to bend them until they are very soft from being in the oven for 45 minutes or more. In that amount of time, some chemical degradation (or something) is causing the cloudiness. If I rig up some way to put a weight on top of the sample, maybe I could speed that up. Or I could just reach in there earlier and do it by hand.

But now I'm out of samples. I can bend and rebend the cloudy ones just to test out some weighting system and/or get my timing right. But I'll only be able to check if the cloudiness disappears if I buy more mirror. Which I can do, but I hate the shipping charges. Ah well.

Tuesday, December 18, 2007

Miscellaneous

  1. I had a long, long thing here about how following my plan was so easy, but it kept reading like Tighter Buns in 30 Days While Eating Pizza, so let's leave it at this: Down by almost 27 pounds.
  2. Way back when, I did some solar experiments. I said I'd come back to that. I'm still working on that. The problem is, the design I came up with is kind of crappy.

    What I want is a parabolic trough mirror focused on a central pipe. I've tried using mylar sheets on various surfaces before, but it didn't come out too well. This time I tried strips of mirror laid in a wooden parabolic form. I haven't tested it yet, but it doesn't look too convincing on the workbench. Lots of gaps, not much total area, not well focused, etc. (No picture, because seriously.)

    While I was wondering what to do about all this, I came across this video. The guy comes across as a little infomercially, but his ideas look pretty good. In particular, I didn't know you could "drape form" plexiglass (aka "acrylic") mirror. That changes everything! Almost zero work and much higher efficiency.

  3. Which brings me to the third misc item. WhereTF do you find acrylic mirror at a reasonable price? I've found it as low as $4.50/sqft, but you have to buy at least $50, not to mention shipping. Plenty of ebayers, but the price with shipping never comes out lower than ~$12/sqft and you have to buy several sqft to get that. Lowe's can special order it, but you have to buy 5 48"x96" sheets and it's still $8/sqft. McMaster-Carr, despite their awesome website, doesn't reveal shipping information even if you ask a live human being, which, HELLO.

    This kind of mirror is used in a lot of children's products because it's shatterproof, so I've considered repurposing a baby mirror, but the cost is still pretty high there due to packaging, frames, etc. I've even wandered around Home Depot and Lowe's to see if I could find a bathroom/decorative/whatever acrylic mirror on some other product. The sole success was a really, really crappy medicine cabinet with attached acrylic mirror. The whole unit was $12 and the mirror was 2 sqft.

    I would just go with that, but the fact that it's attached to something else only proves that I should be able to get the mirror alone for cheaper. Also, I hate to buy something specifically so I can throw it away. In the mean time, I ordered a set of these to experiment with. With the shipping, even amortized over several other items in my order, the price per sqft comes out at lalalaicanthearyou.

Tuesday, November 27, 2007

Tic Tac Lego

The building where I work has several "closed areas" where cellphones aren't allowed in. But of course people still bring their cells to work, plus there are visitors, random construction workers, etc and these people need a place to put their phones while they are inside. So they recently installed a cellphone cubby outside the door to the closed area. The cubby isn't just outside the door, it is also directly across from the main stairwell door that leads to it. It has a very prominent placement, is what I'm saying.

The cubby is a 3x3 array of squares. Every single time I pass it I think of tic-tac-toe. Surely I can't be the only one that thinks of this, so I thought it would be funny to put Xs and Os in there for everyone else to enjoy. But how to make them? Eventually my officemate thought of Lego. Of course!

We actually went through a few designs that were rejected because of strength issues or ugliness or size. Finally I hit on a pretty strong design for both pieces that, if I do say so myself, looks very nice.

Don't these look great? They look like very font-like, I think. Or maybe I'm overthinking it. Anyway, they are exactly the same height and width, which is also exactly the right size to fit the cubbies.

Unfortunately, cameras are even less allowed than cellphones, so I can't take a picture in situ. However, I'm posting this a while after putting it up, so here's a sample of coworker reactions:

  • nothing
  • small, confused smile
  • swapping of X for O to change outcome of illustrated game (happened many times)
  • "Niiiiiice" (in a Korean cleaning lady accent)
  • "Are you the LegoMeister? Nicely done."
  • From my boss's boss: something whispered about tic tac toe I guess he was trying to keep my identity secret?
  • I've noticed many games in progress, with one move played by each passer-by. Also, I've heard reports of some people just standing in front of the cubbies to play a whole game.

Tuesday, November 6, 2007

Tornado in a Box

1: Cut a hole in a box
2: Put your.....no

1: Make a large, square(ish), cardboard tube. Mine is about a meter high and maybe .25 m x .25 m at the base. This is actually two boxes taped together. They aren't even the same size--I just blocked the holes with cardboard and duct tape.

2: On each side, make a slit near the right edge. Or the left edge. But the same for all 4 sides. It doesn't matter which you pick, since you can reverse it by flipping the tube end for end.

The exact width and distance from the edge don't matter too much and you can see I wandered all over the place. Hey, cutting cardboard is kind of hard!

3: Boil some water inside. I went to WalMart for a hotplate but the cheapest one was $20. I tried it on the stove, but that's dangerous and it was hard to see. Then I thought of the bottom of the rice steamer.

Position the tornado box under a light to maximize the reflection from the droplets.

We found that when the steamer was going full....steam, there was too much steam in there swirling around (steam steam steam). So if you turn it on and off every few minutes it might work better. Also, we tried using a steam humidifier but we got nothing at all. I think the steam jet might be coming out too fast and hot. (An ultrasonic humidifier probably has better visibility, but since it isn't hot you'd be missing another vital ingredient.)

The payoff at the end: I asked the Numbers, now that they'd seen a tornado being made, when and where would hurricanes be most likely? In the winter at the North Pole or in the summer at the equator. Ooooooooh, I get it! they said.