Author Archives: Michael Magin

Debian Wheezy (7.1) on Lenovo Ideapad S12

Here’s what I needed to do to get it to work. First, you need proprietary drivers for the 802.11bgn chipset (BCM4312 with LP-PHY). It should be possible to provide this non-free firmware at install time, but I never got that to work so instead I just installed with the wired ethernet and installed this firmware later on the running system by adding the “non-free” and “contrib” repositories to /etc/apt/sources.list and doing:

apt-get update
apt-get install firmware-b43-lpphy-installer

This may require a reboot to take effect, there’s probably another way, but it’s more effort.

You’ll probably also want the proprietary NVidia display driver if you have the NVidia ION chipset variant of the S12. Just follow the instructions at NvidiaGraphicsDrivers for installing the current version using DKMS. Reboot again, or you could reboot once for all three of these changes.

Suspend seems to immediately wakeup due to USB interrupts. Putting the following in /etc/rc.local (and rebooting or executing the script as root) seems to fix that:

for i in 0 1 2 3 ; do
echo USB$i >/proc/acpi/wakeup

Those are the USB controllers, it still wakes up fine from hitting a keypress.

You may also want to add some of the recommended tweaks from powertop. A way to get them in scriptable form is to run it as powertop --html=<filename> option and cut end paste some of that into rc.local. I got things down from about 17 watts to 12 watts on battery.

I haven’t tried to mess with the built-in camera yet.

Bad UI: Error messages you cannot copy and paste

If I get some kind of mysterious error, don’t make me manually retype into my web browser to search. That’s completely ridiculous.

An example:

Admittedly, there’s a link that searches help for the error, but it doesn’t find anything relevant, so I have to go search the web anyway. I’ve seen examples of this from Apple as well on occasion, but I don’t have any handy right now.

By the way, that error is explained by Microsoft here. You’d think with 32 bit error codes like that it would be easy to link to[error code] which would automatically go to the explanation. Or maybe put explanation strings in the application’s message catalogs or whatever. This isn’t 1980.

First time PC board design success (LED cabinet / closet lighting)

Though I’ve designed a PC board for my own production using a toner-transfer etching resist and no holes drilled, I haven’t actually designed a board before for actual commercial production. It’s rather tedious getting everything right the first time, but I managed to make it work.

I was recently playing around with some of the smaller Cree LEDs which are designed for lighting use (in this case, the CLA1B-MKW-XD0F0E83 [pdf] — these are about 12 lumens) and I happened upon an idea for a simple but very useful project. It occurred to me that I would like a little bit of light in the cabinets and closet in our hallway at home without having to turn on an adjacent room light or the crappy wall-mounted light at night. I prototyped a neat little 1.5 volt driver using a Diodes Inc. (formerly Zetex) ZXSC380 [pdf] — this is a better alternative to that “joule thief” circuit that has been going around for some time — and decided that it was sufficient illumination for the purpose. It should provide about 20 hours of operation off a AAA alkaline battery too.

So, after hoping to be able to do something more clever with a low quiescent current and low-voltage hall effect sensor, I gave up and used a SPDT reed switch (the most expensive component in the whole thing at $2.89 each!) so that when a magnet is close to the board, which is mounted just inside of the top of the door opening, it turns off. I expect won’t have to change the battery for years. The magnet is a 1/4″ cylindrical magnet glued in a 1/4″ hole in the door with Gorilla Glue.

I was happy with the price and quality of PC boards from OSH Park, but I certainly wish there was a faster turnaround way to get PC boards made that was also cheap. I did the design with Eagle CAD, which I’d used before a few years ago — but not where I cared about all the layers (copper, drills, holes, solder mask, etc.) I could have gotten the silk screening done better for some of the parts I created outlines for, but it works.

Closet light in operation

Yes, it’s slightly crooked, and it only seems dim with the iPhone flash on.

I’m damned impressed with some of the LED lighting products out there — the better CRI warm white parts are indistinguishable from incandescent bulbs to me. The next thing I’m working on is a lightweight clip-on LED book light for reading in the dark without being too bright. Things are slightly complicated in that I intend to make it USB rechargable, and to make things mechanically neat, I plan to use the Atmel QTouch stuff for the on/off. This will also allow some tricky user-configurable brightness without a tiny trimmer pot, since I know my wife will want hers brighter than I’ll want mine.

Fastest way to check for an empty hash in Perl?

Recently motivated out of curiosity, I and a coworker were benchmarking different approaches to determining if a hash is empty in Perl. Expanding on this a little I present these curious results. In summary, it seems that there are roughly two code paths we’re hitting here. One for if (scalar %hash) and if (%hash), and another for if (keys %hash), if (values %hash), if (scalar keys %hash), and if (scalar values %hash). The latter is much faster when you hit a non-empty hash. It feels somewhat unfortunate that the simplest approach is (approximately) slowest.

hash size: 0
                      Rate if_scalar  if if_values if_keys if_scalar_values if_scalar_keys
if_scalar        3125000/s        -- -3%      -21%    -23%             -24%           -24%
if               3205128/s        3%  --      -19%    -21%             -22%           -22%
if_values        3937008/s       26% 23%        --     -2%              -4%            -5%
if_keys          4032258/s       29% 26%        2%      --              -2%            -2%
if_scalar_values 4098361/s       31% 28%        4%      2%               --            -1%
if_scalar_keys   4132231/s       32% 29%        5%      2%               1%             --
hash size: 3
                      Rate if_scalar   if if_keys if_scalar_keys if_values if_scalar_values
if_scalar         967118/s        --  -1%    -86%           -87%      -87%             -88%
if                978474/s        1%   --    -86%           -86%      -87%             -88%
if_keys          7142857/s      639% 630%      --            -1%       -7%             -10%
if_scalar_keys   7246377/s      649% 641%      1%             --       -6%              -9%
if_values        7692308/s      695% 686%      8%             6%        --              -3%
if_scalar_values 7936508/s      721% 711%     11%            10%        3%               --
hash size: 500
                      Rate   if if_scalar if_scalar_values if_values if_scalar_keys if_keys
if                912409/s   --       -2%             -88%      -88%           -88%    -88%
if_scalar         927644/s   2%        --             -87%      -88%           -88%    -88%
if_scalar_values 7352941/s 706%      693%               --       -1%            -4%     -4%
if_values        7462687/s 718%      704%               1%        --            -3%     -3%
if_scalar_keys   7692308/s 743%      729%               5%        3%             --     -0%
if_keys          7692308/s 743%      729%               5%        3%             0%      --

From the script:

#!/usr/bin/env perl

use strict;
use warnings;
use Benchmark qw(cmpthese);

my %hash_empty = ();
my %hash_small = (1..6);
my %hash_large = (1..1000);

foreach my $ref (\%hash_empty, \%hash_small, \%hash_large) {
  print 'hash size: ' . scalar(keys(%$ref)) . "\n";
  cmpthese(5_000_000, {
    if => sub { if (%$ref) { 1 } else { 0 } },
    if_scalar => sub { if (scalar %$ref) { 1 } else { 0 } },
    if_keys => sub { if (keys %$ref) { 1 } else { 0 } },
    if_values => sub { if (values %$ref) { 1 } else { 0 } },
    if_scalar_keys => sub { if (scalar keys %$ref) { 1 } else { 0 } },
    if_scalar_keys => sub { if (scalar keys %$ref) { 1 } else { 0 } },
    if_scalar_values => sub { if (scalar values %$ref) { 1 } else { 0 } },

No obvious advantage to buying things from versus other online retailers

I bought a window air conditioner from, primarly because if I was told I could return it in a local store.

Last Friday (May 11) it arrived, and it was the right tracking number, but it was actually a microwave oven. Was busy with the new house last weekend and with our cat’s health problems (he’s doing much better now.)

So, this Friday (May 18), we decided to return it in the store nearby. Turns out, in this case, their claim that you can return it locally is a lie, they won’t do that if they shipped you the wrong item — and we confirmed this after calling their 800 number and requesting a return (which I’ll have to drop off at UPS sometime after labeling it.) To add insult to injury, the shipping label page doesn’t load completely (tried with multiple browsers/OSes), and we’re going to have to call them up again.

The one reason I chose them over Amazon, or a couple of much better online retailers for buying small appliances was that I was told I could return it in store, so this is why I will be telling everyone I know not to buy things online from Target. It seems that when “brick-and-mortar” retailers get into online retail, they do a very poor job of integrating both operations. This is somewhat understandable if you think about the business. However, as a customer, you either shouldn’t have to care about such things, or they should be explicit about all the common cases where the return in store is impossible. If they are really trying to provide some benefit over pure-online retailers, they’re failing at that.

(Edit: We finally did get a valid shipping label out of them, shipped it back, and I was credited. Ended up just buying the air conditioner from some random retailer that lists their stuff on Amazon.)