I'm a big fan of Adam Savage's 'first-order retrievability,' the practice of organizing one's tools so that you never need to move any one to get to another. For the many tiny tools I like to keep on my desk, organizing them this way has always been a challenge, so they often just end up in a pile.
I've been passively looking for a solution to this for a while, but never managed to find something that would work for me. Without an available wall, I can't mount an organizer to one, bins and trays take up too much space and would require too much shuffling to find what I need, and pencil holders keep tools from aggregating into a pile, but do nothing to protect each tool from the rest (e.g. protecting fine tweezers from files, or magnetic-pickup wands from everything else).
Borrowing from the idea of a pencil holder, and improving upon it's weaknesses, I quickly made this little organizer.
Parts:
19 plastic tubes from dog waste bag rolls (got these from a dog-walker)
3 in x 3 in scrap of 3/4"-thick poplar
Drill bit of diameter roughly equal to that of the plastic tubes
Hot glue gun
Assembly:
Though the wood can be marked fairly easily with a little geometry, I drilled the holes by eye, using a drill press to keep from drilling all the way through the wood and to ensure even hole depth. I then put a small amount of hot glue into each hole, and pressed the tubes into the holes. Quick and easy!
The whir of a new grind, the sputter of a coffeemaker, the smell of a fresh brew; in a family of avid coffee drinkers, these are among the regular comforts of home life. For much of my life, I didn't understand the allure; I had always found the smell to be a bit off-putting, and never particularly enjoyed the flavor, no matter how well it was masked. One night in college, this chapter came to an abrupt end. In a single moment, as if the universe finally decided to end the cruel joke, that previously unpleasant smell grew intoxicatingly alluring. From that point forward, I loved coffee, and not just any coffee—strong coffee. In the weeks leading up to this build, I had heard quite a few things about cold-brew coffee, but hadn't yet come upon the opportunity to try it. Enticed by the promise of a smooth, sweet-tasting, exceptionally strong brew (!!) without any discernible acidity, I was excited to make some. And with the holidays quickly approaching, this seemed like the perfect gift-giving opportunity for my coffee-loving clan.
Cold brewing: how is it any different?
Most conventional brewing methods, in attempt to extract as much flavor as possible in the shortest acceptable amount of time, introduce heat, pressure, or both into the brewing process, while modulating the coffee-to-water contact area (by way of grind size) to strike a favorable balance between the two. Cold-brewing, as done here or by other methods (see below), takes a very different approach: seeking to maximize flavor at the expense of exceptionally long brew time. The advantages of this become readily apparent with a little experimentation.
Though flavorants and odorants take longer to be extracted from the beans at low brewing temperatures, they are given more time to do so; here, over roughly 8 hours. At low temperatures, however, a different subset of flavors contained within the beans are extracted, some probably unique to cold-brewing (i.e. those that would have been denatured, oxidized, or otherwise modified at higher temperatures).
A drip-rate too high (brew times significantly shorter than 8 hours), results in a brew that is under-extracted, weak, and lacking complexity. A drip rate too low might allow the coffee to warm to room temperature and experience greater oxidation in the room air, resulting in bitterness akin to that of drip coffee that sat out all afternoon. While this won't happen as quickly as for coffee that was hot to begin with, it will eventually happen. For these reasons, starting with ice water (as much ice as can fit, with cold water to fill the gaps) is helpful, and allows for a greater margin of error.
Also of note, drops that pass through the grounds later into the brewing process, which are oily and sweet, taste quite different from those at the beginning of the process, which have more intense 'coffee flavor,' are earthier and are 'buzzier'. The combination of all these flavors are what makes cold brew so magical. Stop your brew too soon (or rush it) and you'll miss out.
How did I do it? Isn't there an easier way?
I'll tackle these in reverse. This is definitely not the only way to make cold-brew, and it's far from the most practical, but it is pretty, and for a gift, that counts for a lot. A few alternatives that I've used, and that admittedly do a great job, include a pitcher specifically designed for making cold-brew (like this one from Takeya) or a French press (like this one from Bodum)—though the pitcher will tolerate a finer grind than the French press, resulting in slightly stronger coffee. For either of them, fill with coffee grounds and cold water, place in the fridge overnight (or longer), and enjoy the next day. Since they are going directly into the fridge, using warm (not hot!) water is okay, and will speed things up a little.
In the apparatus I built, ice-cold water is held in a reservoir at the top and dripped slowly through a series of stages, first through a wine funnel aerator, then into a fritted glass buchner funnel containing coffee grounds, and finally into a wine decanter at the bottom. I chose materials that are safe for contact with a beverage—either materials meant specifically for contact with beverages, or labware made from food-safe materials and designed to be chemically nonreactive—preferentially choosing ones made from glass, so that the long brewing process could be observed and so that the apparatus could be easily sanitized.
Water
For the reservoir, I used a 1 L glass separatory funnel with a PTFE* stopcock (Vee Gee 20149-1000), for its integrated means of drip control. Though seemingly ideal, this choice does come with a few downsides. While the stopcock provides for good adjustability of the flow rate, the sub-drop/s range we aim for is at the bottom of its adjustability range, and thus requires a really fine touch. Additionally, as the separatory funnel is so tall, the stopcock needs to be adjusted several times (usually 3) throughout the brewing process to keep the liquid flowing as the head pressure (liquid level) drops. If you're building one for yourself, choosing a wider, shorter reservoir would minimize this issue; controlling the flow rate directly (e.g. by peristaltic pump) is another option, at the expense of increased complexity and of making the apparatus more difficult to clean.
*While PTFE (teflon) isn't exactly safe at high temperatures, at low temperatures, it's totally safe.
Coffee Grounds
I wanted to avoid using disposable filters, as I didn't want to keep buying them (and disposing of them), and because they absorb some of the oils from the coffee and have a negative impact on flavor. I used a fritted glass buchner funnel with 40-100 µm pore size (Sibata 1311-17100) instead, both to filter and contain the coffee grounds. This allows for a really fine grind size without allowing even a single ground to pass, and is easy to clean.
Initially, I had hoped that a wine aerator (I used this one), with a number of outlet holes spaced evenly around the circumference of the stem), placed between the water and coffee grounds, would help to better distribute the individual water drops over the surface of the coffee grounds. In practice, this wasn't all that effective. If the stem of the aerator is centered exactly below the falling drop, and is perfectly level with the ground, then the falling drops do indeed separate and fall evenly from each of its outlets, distributing the water as intended; if even slightly misaligned, the drops all fall from one of the outlets. If I were building this again, I'd leave it out. What does work well is to place a round of filter paper atop the coffee grounds, as capillary action wets entire filter paper, and wicks into the coffee evenly from there. While this doesn't eliminate the use of filter paper, it also doesn't have any impact on flavor, as it comes in contact with the water before it steeps through the coffee. I used these.
Liquid Gold
At the bottom of the stack, I used a 52 oz. wine decanter (this one). It's glass, it looks good, and it works. I set that on a round 7" cork trivet (IKEA 870.777.00), placed on the bottom platform.
Structure
The structure was made from wooden triangles cut from a 2 ft x 4 ft sheet of 3/4edge-glued poplar (Home Depot), three 3/8 x 36" aluminum rods (Home Depot), and nine small hitch pins (from a $7.50 Harbor Freight assortment), one per rod below each of the middle three triangular platforms, to hold them in place. Lastly, a cork carafe topper (from IKEA, for the LÖNSAM carafe, which has since been discontinued) with a hole drilled through the center was used below the buchner funnel to hold it in place.
To make the cuts, I primarily used a circular saw and jigsaw; for the edge chamfers, a router and 45° chamfer router bit; for the holes, a drill-press (along with a self-centering drill press jig like this one to keep the rods from rolling while drilling holes through their diameter for the hitch pins, and a few small drill bits, spade bits, and large hole-saws).
Brewing
Place the decanter at the bottom. Fill the buchner funnel with finely-ground coffee, a little bit at a time, wetting it slightly as you go (wetting all of the coffee ensures that the water falling from above more-evenly steeps through the grounds). Fill the reservoir with as much ice as possible, and then with water the rest of the way. Adjust the stopcock to achieve a drip-rate of around 2 drops every 3 seconds (assuming a drop size of around 50 µL, this should empty the 1 L reservoir in around 8 hours), and check back every few hours, adjusting the drip rate as necessary.
Also note that while this does, in principle, work with any coffee, freshly (burr) ground, high quality coffee will taste vastly better than the cheapest pre-ground coffee you can buy. A $20 roaster like this one (which comes with 4 lb of free green coffee beans) and a cheap burr grinder will go a very long way.
Olfactory sensory neurons, resident to the olfactory epithelium of the nose, bind directly to odorant (scent) molecules in the air and transmit a signal to the brain in response. To rough approximation, each of these neurons expresses only one or several types of receptor of several hundred (nearly 400 in humans, and more than 1000 in mice), and thus binds with greatest affinity to only one or a few odorants. The electroolfactogram (EOG), recorded at the surface of the olfactory epithelium, is the electrical potential generated across a field of olfactory sensory neurons in response to this binding, evoked upon the presentation of an olfactory stimulus (i.e. scent). As intact signal transduction machinery (present in mature olfactory neurons) is requisite for the presence of EOG signal, and as its dynamics are indicative of the health of the local cell niche, the EOG is a useful functional assay of olfaction at the level of the epithelium.
Justification
I am designing the μEOG (micro-Electroolfactogram) as a compact and low cost device to replace the myriad of bulky and expensive equipment1 (costing on the order of thousands or tens of thousands of dollars) traditionally used for the recording of EOGs from olfactory tissue in a laboratory setting. I aim to create a cheap, precise, mains-isolated, highly noise-resistant biopotential recording system, designed for stimulating and measuring EOGs (but flexible enough to measure other biopotentials with little to no modification), and to make the plans and software freely available for others to use or modify. The conventional EOG monitoring rig consists of a separate amplifier, digitizer, compressed air tank (or two), regulators, and pressurized pulse delivery apparatus, along with a computer (for data collection and experiment control) and other supporting equipment. In this setup, a pulled-glass pipette electrode (containing a chlorided silver wire and electrolyte solution) is gently placed atop a dissected piece of olfactory tissue (a second chlorided silver wire, acting as signal ground, is electrically connected to the tissue by way of the electrolyte solution upon which the tissue rests), and a humidified low pressure, 'high' flow rate (~600 mL/min) odorant-free air stream is aimed across the top of the tissue. Here, absent of a specific olfactory stimulus, a baseline signal is measured. Into the air stream, a 100 ms-long, 10 psi puff of concentrated odorant (e.g. amyl acetate, which smells like bananas) is injected, and the electrical response of the tissue to this olfactory stimulus is measured.
Improvements & Implementation
A large fraction of this setup is dedicated to compressed-air handling; including one or more compressed air tanks (responsible for providing the low and high pressure air streams), multiple regulators, and specialized pressurized air pulse delivery equipment. The μEOG is designed to sidestep this requirement. In the μEOG, these will be replaced with two small diaphragm pumps (like those used to inflate portable automated blood-pressure cuffs): one for the low pressure stream and one for the high pressure pulses. To deliver the high pressure pulses, one of the diaphragm pumps will be pumped against a closed (normally closed) solenoid valve until the pressure (as monitored by a pressure transducer) reaches 10 psi, as compared to atmospheric pressure. At this point, the solenoid valve will be opened for the pulse duration (100 ms by default), and then closed. Pressure will be monitored during this pulse and maintained at 10 psi, though for pulse durations on the order of 100 ms, significant adjustments to the pressure are not likely to be required.
The pumps, air pressure and flow rate control, and all other functions of the setup (including the biopotential amplification, analog filtration, isolation, digitization, and control), will be integrated into a single device, small enough to fit within a 8x 7 x 2.5" enclosure. Device status will be displayed on an LCD on the front of the device, and settings will be adjustable via dedicated rotary switches, potentiometers, and buttons, and via software on a PC connected for data collection. Processing and control of inputs and outputs will be performed by a Teensy 3.1 development board, based on an Freescale ARM Cortex M4 microcontroller (MK20DX256VLH7). Input from the electrodes (run from tissue to device as a shielded twisted-pair) will be passed through a passive RFI-rejection filter (-3 dB bandwidth of 72 kHz) and into an AD623 instrumentation amplifier (in-amp), differentially, with gain set to 100. The REF pin of the in-amp will either be connected to the isolated 2.5 V rail (provided by a TLE2426 rail-splitter, itself supplied by an ROE0505s isolated 5 V-input/5 V-output DC-DC converter) to DC couple the input to the center of the 5 V working range of the ADC, or to the output of an inverted, 0.05 Hz low pass filtered, 2.5 V offset version of the in amp output for DC-rejection (i.e. any components below 0.05 Hz will be subtracted from the signal, rejecting drift due to very low frequency components of the input, or due to DC drift created by RFI noise aliasing in the in-amp). Next, the signal is passed to a digitally adjustable gain stage (gain controlled by digital potentiometer, or digipot) and buffer, to an active fixed-cutoff 4th-order 10 kHz-cutoff Butterworth (Sallen-Key) low pass filter (LPF), an active, digitally-controlled adjustable-cutoff 4th-order Butterworth LPF, and finally to another buffer before being digitized by an external 16 bit, 100 kSPS serial-approximation ADC (Analog Devices AD7680). The output of this is carried over an isolated SPI bus (Analog Devices ADuM7441) to the microcontroller. The cutoff frequency of the 4-pole adjustable LPF is adjusted by changing the resistance of the 4 digipots (2 x dual 256-position Microchip MCP4651) used within two cascaded 2-pole Sallen-Key LPF stages, optimized to closely match ideal 4th-order Butterworth filter parameters using MATLAB, signaling these changes over an isolated I2C bus (Texas Instruments ISO1540).
MATLAB Filter Optimization
First, let's define a few functions that will be useful later on:
SKB_LPF_generic.m
functionoutput =SKB_LPF_generic(fc,poles)% SKB_LPF_GENERIC Creates the transfer function of a 2, 4, 6, or 8-pole% Butterworth low pass filter with a given -3dB cutoff frequency, built% from 2-pole filter stages.%% Returns a structure array containing:%% - vectors of the coefficients (ordered by descending power of s)% of the numerator and denominator of the transfer function of each% 2-pole stage,%% - vectors of the coefficients of the numerator and denominator of the% transfer function of the filter as a whole (from the cascaded 2-pole% stages), and%% - the continuous-time transfer function of the entire filter.%% OUTPUT = SKB_LPF_GENERIC(fc,poles)%% OUTPUT.n1 ... OUTPUT.n4 numerator coefficients of individual stages% OUTPUT.d1 ... OUTPUT.d4 denominator coefficients of individual stages% OUTPUT.n numerator coefficients of whole filter% transfer function% OUTPUT.d denominator coefficients of whole filter% transfer function% OUTPUT.cascade complete continuous-time transfer function%switchpolescase2Q=[0.7071];output.n1=(2*pi*fc)^2;output.d1=[12*damping_ratio(Q(1))*(2*pi*fc)(2*pi*fc)^2];output.n=output.n1;output.d=output.d1;output.cascade=tf([output.n],[output.d]);case4Q=[0.54121.3065];output.n1=(2*pi*fc)^2;output.d1=[12*damping_ratio(Q(1))*(2*pi*fc)(2*pi*fc)^2];output.n2=output.n1;output.d2=[12*damping_ratio(Q(2))*(2*pi*fc)(2*pi*fc)^2];output.n=multpolys(output.n1,output.n2);output.d=multpolys(output.d1,output.d2);output.cascade=tf([output.n],[output.d]);case6Q=[0.51770.70711.9320];output.n1=(2*pi*fc)^2;output.d1=[12*damping_ratio(Q(1))*(2*pi*fc)(2*pi*fc)^2];output.n2=output.n1;output.d2=[12*damping_ratio(Q(2))*(2*pi*fc)(2*pi*fc)^2];output.n3=output.n1;output.d3=[12*damping_ratio(Q(3))*(2*pi*fc)(2*pi*fc)^2];output.n=multpolys(output.n1,output.n2,output.n3);output.d=multpolys(output.d1,output.d2,output.d3);output.cascade=tf([output.n],[output.d]);case8Q=[0.50980.60130.89992.5628];output.n1=(2*pi*fc)^2;output.d1=[12*damping_ratio(Q(1))*(2*pi*fc)(2*pi*fc)^2];output.n2=output.n1;output.d2=[12*damping_ratio(Q(2))*(2*pi*fc)(2*pi*fc)^2];output.n3=output.n1;output.d3=[12*damping_ratio(Q(3))*(2*pi*fc)(2*pi*fc)^2];output.n4=output.n1;output.d4=[12*damping_ratio(Q(4))*(2*pi*fc)(2*pi*fc)^2];output.n=multpolys(output.n1,output.n2,output.n3,output.n4);output.d=multpolys(output.d1,output.d2,output.d3,output.d4);output.cascade=tf([output.n],[output.d]);``
otherwisedisp('Please enter an even number of poles between 2 and 8.');returnend
multpolys.m
function[out] =multpolys (varargin)% MULTPOLYS Multiplies the coefficient vectors of 2 to 4 single-variable % polynomials together. The coefficients of each input vector must be % ordered from highest to lowest power.% switchnargincase2out=conv(varargin{1},varargin{2});case3out=conv(conv(varargin{1},varargin{2}),varargin{3});case4out=conv(conv(conv(varargin{1},varargin{2}),varargin{3}),varargin{4});otherwisereturnend;
damping_ratio.m
function[Z] =damping_ratio(Q_factor)% DAMPING_RATIO Calculates the damping ratio (Z) of a filter stage from its% Q-factor, where Z = 1 / 2Q. Accepts as input a single Q-factor or an% array of Q-factors (e.g. a Q-factor for each stage of a higher-order % filter).%Z=1./(2.*Q_factor);end
And here's the meat of the calculations; the main function file. It was written (and is evaluated) sequentially, first to describe the ideal (model) version of each filter, then to determine the best combination of real component values needed to fit those models across the range of desired cutoff frequencies, and lastly to compare these to the ideal.
uEOG_LPF.m
%% uEOG 8th order Low Pass Filter Design%% REFERENCE: most of this information is contained in the separate function% files, but is kept here for future reference.%% 8 Pole Sallen Key Butterworth Quality factors: % Q1 = 0.5098, Q2 = 0.6013, Q3 = 0.8999, Q4 = 2.5628%% 4 Pole Sallen Key Butterworth Quality factors: % Q1 = 0.5412, Q2 = 1.3065%% o-----C1------------o% | |\ |% Vin---R1---o---R2---o-----|+\ |% | | \-o---Vout% C2 o-|- / | % | | | / |% GND | |/ |% o------o%% Pass band gain K = 1 for all stages (2-pole pairs)% Corner frequency: fc = 1/(2*pi*sqrt(R1*R2*C1*C2))% Quality factor: Q = 1/(2*Z) = sqrt(R1*R2*C1*C2)/(R1*C1 + R2*C1 + R1*C2*(1-K))%% Transfer function of each 2-pole stage (which are cascaded into a higher% order filter):% H(s) = V_out(s)/V_in(s) = ((2*pi*fc)^2)/(s^2 + 2*Z*(2*pi*fc)*s+(2*pi*fc)^2)%%% Initializeclc;clearall;closeall;%% Prototypical 8-pole Butterworth LPFfc=10000;poles=8;% Calculates the transfer function numerators and denominators for each% 2-pole stage of the prototypical filter, and the numerator, denominator, % and transfer function of the entire filter (all stages combined)RCideal=SKB_LPF_generic(fc,poles);% p = bodeoptions; p.FreqUnits = 'Hz';% h = bodeplot(RCideal.cascade, p); grid MINOR
%% Determine the actual component values for the 4th order adjustable filter section, verify% Calculate resistance values realizable using MCP4017 & MCP4018 digipots% (datasheet specifications: 100ohm wiper, 128bit 10k or 50k digipot) with% series 100ohm resistor (in case of 50k digipot):%% for i=0:127% Rvals50k(i+1)=100+100+i*(50000/127);% Rvals10k(i+1)=100+i*(10000/127);% end% Calculate resistance values realizable using MCP4651 digipots (datasheet % specifications: 75ohm wiper, 256bit 10k or 50k digipot)fori=0:256Rvals50k(i+1)=100+75+i*(50000/127);Rvals10k(i+1)=75+i*(10000/127);end% From the calculated realizable digipot resistance values, find the % closest real-world matches to the calculated optimal filter resistancesfori=1:length(RCfilter.fc34)[~,I31(i)]=min(abs(Rvals10k-RCfilter.R31(i)));[~,I32(i)]=min(abs(Rvals50k-RCfilter.R32(i)));[~,I41(i)]=min(abs(Rvals10k-RCfilter.R41(i)));[~,I42(i)]=min(abs(Rvals50k-RCfilter.R42(i)));endRCfilter.R31IRL=Rvals10k(I31);RCfilter.R32IRL=Rvals50k(I32);RCfilter.R41IRL=Rvals10k(I41);RCfilter.R42IRL=Rvals50k(I42);% Calculate filter parameters using actual component valuesfori=1:length(RCfilter.fc34)RCfilter.fc3IRL(i)=fc(RCfilter.R31IRL(i),RCfilter.R32IRL(i),RCfilter.C31,RCfilter.C32);RCfilter.Q3IRL(i)=Q(RCfilter.R31IRL(i),RCfilter.R32IRL(i),RCfilter.C31,RCfilter.C32);RCfilter.Z3IRL(i)=Z(RCfilter.R31IRL(i),RCfilter.R32IRL(i),RCfilter.C31,RCfilter.C32);RCfilter.transfer3(i)=RCtransfer(RCfilter.fc3IRL(i),RCfilter.Z3IRL(i));RCfilter.fc4IRL(i)=fc(RCfilter.R41IRL(i),RCfilter.R42IRL(i),RCfilter.C41,RCfilter.C42);RCfilter.Q4IRL(i)=Q(RCfilter.R41IRL(i),RCfilter.R42IRL(i),RCfilter.C41,RCfilter.C42);RCfilter.Z4IRL(i)=Z(RCfilter.R41IRL(i),RCfilter.R42IRL(i),RCfilter.C41,RCfilter.C42);RCfilter.transfer4(i)=RCtransfer(RCfilter.fc4IRL(i),RCfilter.Z4IRL(i));end% Calculate transfer functions using actual digipot resistancesRCfilter.transfer34=RCfilter.transfer3.*RCfilter.transfer4;% p = bodeoptions; % p.FreqUnits = 'Hz';% h = bodeplot(RCfilter.transfer3(4), RCfilter.transfer4(4), RCfilter.transfer34(4), p); % grid MINOR
Software (work-in-progress; more details to be released as more of the project is finalized)
References
[1]: Cygnar, K. D., Stephan, A. B., Zhao, H. Analyzing Responses of Mouse Olfactory Sensory Neurons Using the Air-phase Electroolfactogram Recording. J. Vis. Exp. (37), e1850, doi:10.3791/1850 (2010).