Tuesday, February 16, 2021
VL53L0X NIR laser time-of-flight distance sensor with cover
Wednesday, January 13, 2021
Hummingbird nectar recipe by weight (grams)
Online resources say 1:4 sugar to water ratio by volume. This translates to about 1:5 by weight
To be more precise: 0.25 cups sugar is 48 g, 1 cup water is 237 g, so the ratio is 1:4.9375 or 0.2025:1 or 16.8% sugar by weight. For my small feeder, I do 30 g sugar to 150 g water.
Remember to use only refined white sugar. Online resources say that substitutes (e.g. organic sugar that is a bit darker) may be bad for the birds.
Friday, June 17, 2016
Smoked trout on a Weber Q1200
I came up with the following method. I have repeated this multiple times and have been very pleased with the results. Definitely interested to hear others' suggestions.
The Weber Q1000/Q1200 are the smallest gas grills Weber makes. For a gas grill, you want wood chips rather than wood chunks to smoke with. I use these:

One option I have seen is just to wrap the chips in foil and put the packet directly on the fire. Instead I put the foil in a standard 10 inch Lodge cast iron pan:

Cover the pan with foil:

Poke holes in the foil:

And put the pan on the grill:

This just fits inside the Q1200. I heat this on full gas until it starts smoking. (I've also tried heating it on the stove to get it going while I dress the fish, which works fine if you don't mind getting a little smoke inside the house.)
To prep the fish, just simple salt and pepper and some lemon and shallot slices tucked inside tastes great. I would say the shallot is really key.

To cook the fish gently without putting it too close to the heat, I lay it on top of the foil-covered pan. To prevent sticking it helps to oil the foil, or else just put a layer of lemon slices or greens in between the foil and the fish.

I then cover the whole thing with more foil to keep the smoke in. Some other cover would be more convenient here, perhaps a large pie tin?

Cooking time depends a bit. I'm not that interested in slow / cold smoking, so I just leave it at 3/4 gas and close the lid. The built in thermometer says the grill is ~350 F. For whole fish I do this 10-15 minutes each side. You could definitely play with lower heat and longer if you want. Or if you want to get to eating faster you can throw the fish straight on the grill for a minute after smoking is done.
This one didn't turn out so pretty; not enough insulation between fish and foil. But tastes wonderful!
Saturday, May 21, 2016
Update 3: DIY Hario conical burr grinder Kitchenaid stand mixer attachment
With the additional set screw, I have been using this piece intermittently for over a year without it wearing out. Please note that I believe this can put stress on the KitchenAid motor if you are trying to do a very fine grind or if you are using harder coffee beans (e.g. light roast).
I've been using this with both my larger and smaller Hario burr grinders. For the small grinder with the pentagonal driver, I found a stainless steel adapter available here. There are other sellers with similar items; I don't know whose design was first but this seller is amiable.
Monday, September 7, 2015
Mount Auburn Cemetery Map and Key
Saturday, March 2, 2013
LIRC RasPi remote control configuration for GE Air Conditioner
I found that our Samsung BN59-00857A remote worked fine with an existing lircd.conf configuration file for the BN59-00856A. (Actually the 00856 includes a few additional buttons not on the 00857; several of these work for controlling our TV even though they're not on our OEM remote!)
When it came to controlling our GE air conditioner, I didn't find any existing configuration file. The process of getting a working config file together was a little more involved than I expected, so I'm detailing it here and posting the resulting config (also sent it to the LIRC maintainers, but didn't hear anything back).
I knew from running mode2 that raw signals from the AC remote were being received correctly. But I wasn't able to get irrecord to pick up the AC remote signals even when forcing it into raw mode. It turns out that the GE AC remote has an unusually long code length, 48 bits, so maybe that was part of the issue. I'm also not clear on whether my irrecord was going into raw mode correctly; seemed to behave exactly like non-raw mode so maybe there's a problem with the version built for Raspbian?
Anyway, to get a config file, I had to pipe the mode2 raw data to text files and then manually pull the text into a raw conf file and filter out the "pulse" and "space" text (thanks vim). I confirmed that the resulting raw file works for controlling the AC through LIRC. Then I used irrecord -a to retroactively convert the raw codes into a more succinct config file. Looking at the various wall mount ACs GE sells, it seems likely to me that these codes will work for any unit since the controls all look the same. (If you have a heat+cool unit then you'll be missing the "heat" button since my AC doesn't have that.)
Hope it's useful. If you want the raw version of the conf file for some reason, just ping me for it.
# this config file was automatically generated
# using lirc-0.9.0-pre1(emulation) on Sat Mar 2 14:09:22 2013
#
# contributed by Peter Li
#
# brand: GE
# model no. of remote control:
# devices being controlled by this remote: All the GE wall mount air
# conditioners look like they have very similar controls, so I would guess this
# will work for all. It will probably also work for the Heat/Cool wall models,
# other than the missing heat button, but I haven't tried that.
#
begin remote
name GE_AirConditioner
bits 48
flags SPACE_ENC
eps 30
aeps 100
header 3388 1678
one 430 1257
zero 430 412
ptrail 428
gap 40991
toggle_bit_mask 0x0
begin codes
on_stop 0x555AF308598F
cool 0x555AF3081D8F
fan 0x555AF3085D8B
tempup 0x555AF308D987
tempdown 0x555AF308198B
timeron 0x555AF308D58B
timeroff 0x555AF308958F
hi 0x555AF308DD83
mid 0x555AF3083D8D
low 0x555AF308BD85
sleep 0x555AF3085583
end codes
end remote
Tuesday, January 15, 2013
CDC Infant Growth Curves in Google Docs/Drive Spreadsheet
Saturday, July 28, 2012
Update 2: DIY Hario conical burr grinder Kitchenaid stand mixer attachment
Managed to get a pretty decent locating fit for a 3/8" x 5/8" x 5/32" sealed, pre-lubricated ball bearing from VXB. They have a lot of options in this size. I ordered two to choose from, but only one fit into the printed flange piece easily with just my hand pressure even though they were rated for the same maximum OD and tolerance. So I think the current design is close to the edge of hand pressed fitting for the low tolerance of the current SLS 3D printing process.

If you look carefully at the bottom edge of the flange where it contacts the drill adapter, you can see there is a step-wise pattern; this is because I tried to give the surface that contacts the drill adapter a gentle slope to match the slope on the front surface of the drill adapter. It basically works, but the 3D printing leaves this step pattern instead of a smooth slope. Probably not worth the trouble.
Here's the whole thing assembled. Note that the square driver piece is taking on a healthy coffee color due to the plastic material being porous and absorbing bits of coffee grounds. I've had this piece a while now and it's showing no signs of failing, so I think the 3D printed parts are reasonably successful for medium use. It's also kind of nice to know that the plastic part will fail before you kill the KitchenAid motor if you happen to jam things up some how.

Here's a picture of the extra 5/8" OD bearing I bought that didn't quite fit nicely. I also bought a 9/16" OD needle bearing to try, but it seemed better to stick to something with less depth and the 5/8" OD ball bearing was a small enough OD to work.
Sunday, May 20, 2012
Update: DIY Hario conical burr grinder Kitchenaid stand mixer attachment
Update 2: It seemed like a Wiki was actually more appropriate, so I am retiring the Google Group in favor of a new Wikia page. Please join in!
Update: I created a Kitchenaid DIY Google Group to try to get together some of the handful of people who have been hacking on this. Also posted a listing of known projects.
Substantial updates to the earlier prototype. Here I've added an adapter flange that holds it in place against the Kitchenaid adapter hub. This was also supposed to house a sleeve bearing but I made the dimensions too tight so that will have to wait for next iteration. Also I found some nice, small, cheap, sealed ball bearings from VXB so will probably design for that instead. The coupling between the square hub and the 3/8" drill shaft is essentially the same as before, only shorter to leave room for the flange.

Here's a video of this version in action. Note that now I'm using it to drive the older Hario conical burr grinder model, rather than the Hario Slim. (We have both, one for home and one for my office. Kitchenaid only at home though ;).)
One advantage of the older Hario is that the coupling from the drill adapter to the grinder is simpler. The Hario Slim uses a pentagonal (AKA 5-point) drive in a small nonstandard size (~3/16"). I tried a 3D printed adapter for that but I don't think the Shapeways "Strong, Flexible" material is strong enough. I'm trying a lasercut acrylic piece next.
For the older Hario, the situation is much simpler. The drive has a nonstandard shape (cylindrical with flats on two opposite sides) for hand cranking, but it's also threaded as M6-1 so you can just screw something down on top of it. Actually, you can even just clamp the drill adapter directly down on this, as jeffkobi did in his original design. I wanted to try something simple and off-the-shelf to avoid clamping directly to the grinder, so I looked for M6-1 coupling nuts that would fit into the 3/8" drill adapter, but unfortunately they are all slightly too large. However, a 1/4-20 coupling nut fits snugly into the adapter (you may have to test a few to find one with clearance) and screws smoothly onto the grinder drive for the first few turns. I don't have any MechE, so can't really tell you the relative benefit of either clamping directly to the drive or screwing an unmatched thread onto it, but as long as I include some washers so that the 1/4-20 is only riding the M6 threads a little way I think this might be a little nicer. An M6@1/4-20 adapter nut or just an M6 with a smaller outer diameter would be ideal but I haven't found such a product.

The previous hub coupling has already worn out, so it's still not clear whether these 3D printed parts are viable. The first thing to go was the set screw holes; on the failed piece the screws get pushed back through their threads so the coupling no longer grips the 3/8" shaft. But I think the mistake there was to tap the holes and use nylon set screws before switching to steel set screws. On the new piece I just screwed steel set screws through the untapped hole so the fit is tighter and it seems to be holding up better so far. Probably a clamping adapter design would be better, although it would be a tight fit and I'm not sure how well 3D printed plastic would handle that kind of stress.
Sunday, April 15, 2012
Kitchenaid drill adapter
Update: here's a video of it in action with the drill adapter clamped directly onto a Hario Slim Burr Grinder. Actually works pretty well as is, so I will put the piece on Thingiverse soon. Lots of refinements planned though.
A while back I had a brief flirtation with the idea of DIY Kitchenaid attachments, but never really got going on the project. Then recently, jeffkobi posted a nice Instructable on how to attach a Kyocera manual burr coffee grinder to your Kitchenaid and it rekindled my interest (not least because I own the same model burr grinder).
I really liked jeffkobi's idea of using an inexpensive Milescraft 90 degree drill adapter as the intermediary between the mixer and the grinder. So I've been trying to develop some simple 3D printable pieces to make it easier to couple the drill adapter to the Kitchenaid attachment hub. This is a work in progress and is going to take at least one more iteration to refine, but I'm pretty happy with how it looks so far, so here's some teasers.
Thursday, March 15, 2012
Matlab internals and in-place editing
Friday, September 2, 2011
HOWTO: deploy multithreading on Matlab with the Theron C++ Actors library
Building multithreaded Matlab mex files with Theron
This was pretty straightforward on the Mac, somewhat tricky but not terrible on Linux. I don't have any working C++ compiler with Matlab on Windows thanks to absolutely abysmal support from Microsoft and Mathworks (essentially Mathworks only supports Microsoft and Microsoft's compilers are impossible to get installed correctly). But the notes below may help you get things working on Windows anyway and I added some Windows specific notes at the very bottom. Before trying to get Theron working, I encourage you to write a simple C++ mex program (maybe a single-threaded version of your planned algorithm) and get it built on Matlab first, to confirm that your system is correctly set up for mex.
I'm fairly confident most Mac users can get this working. On Linux I have only tested on 2010 and 2011 64-bit versions of Matlab, and there are reasons to fear that earlier versions may have more trouble working. Fair warning.
Simple(r) concurrent Matlab programming with Theron
Preamble: What follows are my (long-winded) musings on the current (Sep. 2011) state of concurrent programming in Matlab. For a specific guide to using the Theron C++ library for Actors concurrency in Matlab, see the following post.
Concurrent Matlab
Matlab is a standard programming environment for scientific calculations. In our lab, we use it for a lot of analysis, especially prototyping new analyses. Eventually, some of the performance critical stuff gets ported over to Java, but we still have plenty of things we need to run that are Matlab-only and need to be fast.
As personal computers add more and more cores without improving clock speeds much, there is more and more need for parallelized (AKA concurrent, multithreaded) software. Matlab is not a very popular language for supercomputing, but high-performance clusters also of course demand parallelized software. Matlab has some support for multithreading internally, so depending on which Matlab internal functions you use, you may see significant multicore use on your machine. But there is currently no support for explicitly writing multithreaded programs in vanilla Matlab.
Thursday, August 4, 2011
Broken Mac OS 10.6 (and 10.7 and 10.8 and...) Java
Apple has a pretty lousy history with Java support, but this still surprised me. If you are having trouble getting programs to compile with older Java versions (e.g. for backward compatibility), you might want to take a look in this directory: /System/Library/Frameworks/JavaVM.framework/Versions
Here's what I found on my OS 10.6 system:
lrwxrwxr-x 1 root wheel 5 Jun 29 13:37 1.3 -> 1.3.1 drwxr-xr-x 3 root wheel 102 Feb 11 2010 1.3.1 lrwxrwxr-x 1 root wheel 10 Jun 29 13:37 1.4 -> CurrentJDK lrwxrwxr-x 1 root wheel 10 Jun 29 13:37 1.4.2 -> CurrentJDK lrwxrwxr-x 1 root wheel 10 Jun 29 13:37 1.5 -> CurrentJDK lrwxrwxr-x 1 root wheel 10 Jun 29 13:37 1.5.0 -> CurrentJDK lrwxrwxr-x 1 root wheel 10 Jun 29 13:37 1.6 -> CurrentJDK lrwxrwxr-x 1 root wheel 10 Jun 29 13:37 1.6.0 -> CurrentJDK lrwxrwxr-x 1 root wheel 59 Jun 29 13:37 CurrentJDK -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents
I kept trying to get Eclipse to compile with 1.5 and kept getting incompatible binaries. Thanks Apple! YMMV, but I found this post a good guide to getting a real Java 1.5 installation.
Thursday, July 28, 2011
Mac OS 10.6.8 breaks OpenSSL dev compatibility
Update (2011-07-29): Globus Toolkit devs have told me that this is a frequent problem with Mac OS updates. Thanks Apple. So they recommend running with the --without-openssl-header-check flag if you don't want to go to the trouble of actually installing compatible headers.
If you are trying to build anything that requires OpenSSL on Mac OS 10.6 and have updated to 10.6.8, you may run into the following complaint:
checking OpenSSL header version... 9080cf (OpenSSL 0.9.8l 5 Nov 2009) checking OpenSSL library version... 90812f (OpenSSL 0.9.8r 8 Feb 2011) checking whether OpenSSL's headers match the library... no configure: error: Your OpenSSL headers do not match your library. Check config.log for details. If you are sure your installation is consistent, you can disable the check by running "./configure --without-openssl-header-check". Also see contrib/findssl.sh for help identifying header/library mismatches.
For some reason, when Apple upgraded to OpenSSL 0.9.8r to address security issues they failed to update the headers, so now there is a version mismatch (i.e. header version is 0.9.8l but library version is 0.9.8r).
If you want to track this issue in more detail, you can find a copy of the findssl.sh script, either on your system somewhere or just find it online. If you download it online, you will probably have to hack the script to find Mac's .dylib shared library files instead of the Linux standard .so files. Alternatively, just try these commands:
locate opensslv.h locate libcrypto.dylib
That should show you where the different versions of headers and libs are respectively. Then you can look inside the opensslv.h file in /usr/include and confirm that it is 0.9.8l instead of 0.9.8r.
In any case, the solution seems to be:
- Get OpenSSL 0.9.8r from http://www.openssl.org/source/
- Untar, copy the include/openssl directory to somewhere like /usr/include/openssl-0.9.8r
- Point your build to these new headers. I decided to just blast the incompatible headers, so I moved my old /usr/include/openssl to /usr/include/openssl-0.9.8l and then symlinked openssl to openssl-0.9.8r.
- Now it builds!
Friday, April 22, 2011
Combining USDA SR23 with glycemic index data
USDA provides a National Nutrient Database for Standard Reference currently in Version 23 (SR23), which has loads of nutritional data on a good selection of food products. On my wishlist would be cross-referencing with UPC bar codes, as well as some additional data that are currently missing, such as glycemic index and separate soluble vs. insoluble fiber values.
I did find one website that has done a pretty job with glycemic index already: nutritiondata.self.com. In addition to pulling in glycemic index data, they've also calculated glycemic load and then built a statistical model to try to infer/impute glycemic load for foods that don't have published glycemic index data. And they also have some other summary statistics that they've developed in-house such as "Fullness Factor" and an overall healthiness rating. Kudos to them, but I wanted to play with these data myself. Also I didn't see a fiber breakdown there.
One data source I found that has both glycemic load and soluble vs. insoluble fiber (at least for some entries) is the Diet History Questionnaire II (DHQ2). The DHQ is available to download as a single giant table. I plan to play with this.
Another option is to link the glycemic index data derived for the DHQ back to SR23. This appears to be possible thanks to a couple of additional tables. First, DHQ provides their glycemic index data in a table referenced against food codes from the USDA Continuing Survey of Food Intakes by Individuals (CSFII). These codes match the food codes used in the USDA Food and Nutrient Database for Dietary Studies (FNDDS). The FNDDS database includes a table that links selected FNDDS/CSFII codes back to one or more SR23 codes. (Since my main interest in glycemic index is to compare glycemic index to sugar composition, and FNDDS only has a value for total sugar not individual components, I'm not too interested in FNDDS by itself.)
I'll be exploring DHQ vs. SR23 (augmented with glycemic indices linked from FNDDS+DHQ) and will report back.
Sunday, February 20, 2011
Globus Toolkit 5.0.3 on Cygwin 1.7
Cygwin patches (see earlier post) did not make it into GT5.0.3. The patch requirement is therefore the same as for GT5.0.2 (see earlier post). These patches may make it into future distributions.
I took slightly more detailed notes during the 5.0.3 build process, so you can now find more details about which packages require patches here.
Monday, February 14, 2011
DIY KitchenAid attachments
Update: (2011-03-14): So this does not quite fit perfectly into the Attachment Hub, but it is good enough that with a housing for the shaft I'm pretty sure it will work. I'll take more precise measurements and post any updates.
Update (2011-02-18): Arrived no problem from Mending Shed; Parcel Post was quite fast actually. Don't have the KitchenAid here with me right now so will not be able to test at all for a few weeks.
Our KitchenAid stand mixer is probably the fanciest piece of hardware we own other than our car. I've been thinking for a while that there really ought to be a DIY modding community around this appliance; it's a powerful, well built kitchen motor waiting to be exploited (plus planetary gearing if that is helpful). But I haven't found much so far. Here's one nice rotisserie mod I found, and that's about it.
KitchenAid makes a number of official attachments. Some of them attach to the bottom head where the planetary gearing is, while others attach to a port on the front (the "Attachment Hub") that accepts square shafted ("Power Shaft") attachments. I searched around a little and was able to find a part that I'm pretty sure will fit the attachment hub: KitchenAid 9709315, the "clutch shaft". Amazon sells it.
Note that this doesn't include the shaft housing that will allow you to lock it into place; figuring out a way to hack this together will be the first job before anyone can really use this thing for DIY projects. I'm wondering if putting something together in plastic through Ponoko or the like will get the job done. It probably requires some bearings too.
I ordered one from Mending Shed (slightly cheaper than Amazon and will ship Parcel Post), will update with progress.
Friday, November 19, 2010
Faster median calculation and generic rank selections in MatLab via nth_element
C++ std::nth_element is a standard specification for an efficient rank selection algorithm. This algorithm can be used to solve a number of rank selection problems efficiently.
One example is median finding. A naive median finding algorithm, as implemented in MatLab (at least up to R2010a) is to sort the entire list of values and then just take the value in the middle position. But sorting the entire list is overkill; it is more efficient to do a sort of partial sort just to the point where the desired value is in the correct position. The version of this typically implemented in nth_element is known as quickselect or Hoare's Selection Algorithm. See Wikipedia: Selection algorithm for more details.
I find that a MatLab fast_median function based on nth_element runs about twice as fast as the native MatLab median function based on sort. Theoretically, the average complexity of quickselect is O(n), while the best performance complexity of the sort based method is O(n log n).
Finding median values is central to robust statistics, for example calculating the Median Absolute Deviation.
If you are interested, my MatLab wrapping of nth_element and an example implementation of fast_median are available at MatLab Central File Exchange.
Thursday, October 14, 2010
Startup GNU Screen with multiple regions (split screen)
Since I've been doing a lot of work remotely lately I've been brushing up my GNU Screen skillz.
One thing I'd like is to be able to reattach a screen with a number of regions (AKA split screens) setup automatically. Screen is supposed to get this in the next release, but it's been a while.
In the meantime, the following kludge seems to work well enough: (sleep 0.1; screen -X split) & screen -r. Basically, this says: "reattach to my screen and at the same time in the background wait a fraction of a second and then send the split command to screen from a separate thread".
This was a common enough pattern that I wrote it into a little shell script:
#!/bin/sh splits=$1 if [ -z $splits ] ; then splits=1 fi sleep=$2 if [ -z $sleep ] ; then sleep=0.1 fi sleep $sleep i=0 while [ $i -lt $splits ] ; do screen -X split screen -X focus bottom screen -X select `expr $i + 1` i=`expr $i + 1` donewhich is used: splitscreen 4 & screen -r.
There's plenty of room for improvement. A more principled replacement for the call to sleep would be to monitor the socket files. In my Mac OS 10.5 these are under /tmp/uscreens/.... (I believe the standard location is /usr/tmp/screens/...) This is purely empirical, but it appears the user permission on the socket file changes from -x to +x (i.e. becomes executable) when the screen is attached. So instead of sleep we should be able to do a wait until that permission change occurs.
In principle I think this could even be used to save and restore region settings. For example, rebind the split key to not only split but also save a flag to filesystem indicating how many regions, then read this flag when reattaching. Or we could just wait for the next release...
