Gas station without pumps

2014 July 14

End of an era

My son has his last performances at West End Studio Theatre this summer—his last summer before college.  He has had theater classes with Terri Steinmann and various of her staff members since the Wizard of Oz class in July 2004, and he has been performing on the WEST stage since they opened in 2007.  Between Pisces Moon (where Terri taught before founding WEST) and West Performing Arts, he has done at least 42 classes with them (I’m not sure how to count the Dinosaur Prom Improv troupe, which he performed with for two years—I counted that as only one class, though it probably should count as more, as there were weekly practice sessions for the two years).  Adding up all the course tuition over the 10 years he’s worked with them, I think we’ve paid around $20,000, averaging$2k a year—well worth it for the pleasure and the learning he has gotten from it.

This past weekend he performed as Otho (the interior designer) in Betelgeuse. After seeing the movie, I did not know how they would pull it off as a stage play, but they did quite a good job of it—particularly since they did not have the complete script until a few days before they performed (a long-standing WEST tradition of writing the script after rehearsals have started).  There were two casts (the morning class and the afternoon class), but I only saw the afternoon cast’s production—I understand that the interpretations of essentially the same script and set were quite different for the two casts (costumes had to be different, because the actors were very different sizes).

He has one more class with them this summer—the summer teen conservatory with Santa Cruz Shakespeare, which I believe still has room for another student or two (the conservatory is limited to about 12 students).  He’s done their Shakespeare teen conservatory for the past four years—it is quite different each time. The conservatory is probably West Performing Art’s most advanced theater class.

After this summer, not only will he be finished with West Performing Arts, but the West End Studio Theatre, where about half his performances have been, will be closed. We joke that they can’t go on without him, but the truth is that they are losing their lease.  They’ve been renting on a year-to-year contract for eight years, and the landlord has found a tenant (a beer brewer) willing to lease the space on a longer term lease.  The parting is amicable, but everyone will miss the W.E.S.T. space, which has been much more flexible and functional than any of the other spaces children’s theater has used around the city.

West Performing Arts will continue classes at the Broadway Playhouse and at schools, but they’ll need more space for classes than Broadway Playhouse can provide, especially for their popular summer classes, so they are looking for a new home. If anyone knows of spaces that might meet their needs (ideally, two large adjacent spaces that can be used for classes, one of which can be a flexible performance space, totaling about 10,000 sq ft, with storage, office space, and nearby parking and not needing a lot of renovation).  They don’t have a lot of money (they’ve been keeping the classes affordable), so the typical $15–20/sq.ft./year leases locally are probably beyond their means. If anyone has any leads for them, their contact information is on their web site. 2014 July 12 Impostor syndrome Filed under: Uncategorized — gasstationwithoutpumps @ 10:56 Tags: I know that many students feel at times like they aren’t capable of doing what they need to do to ace their classes, to graduate, to move on into the “real world” or higher up in academia. Sometimes they feel like they are just “faking” being smart, and that someone will catch them at it. This is known as “impostor syndrome” and is quite common—Wikipedia even has a page explaining it. People from underprivileged backgrounds or who have been socialized to think of themselves as somehow inferior suffer from it more than those who have been taught to be confident in what they do. For example, women in physical and computational sciences often doubt themselves, even when the objective evidence is that they are quite capable. Even tenured professors, who have passed through many tests of their resolve and ability, often suffer from impostor syndrome. I suggest the following reading (all from a single author) for those who are wrestling with this problem (the author selected these posts herself from her larger body of work): http://academic-jungle.blogspot.com/2013/01/underachieving.html http://academic-jungle.blogspot.com/2013/11/beer-fries-and-impostors.html http://academic-jungle.blogspot.com/2013/08/the-sucky-and-awesome-of-academia.html http://xykademiqz.wordpress.com/2014/04/27/potential-and-ambition/ http://xykademiqz.wordpress.com/2014/03/13/tenure-denials/ http://xykademiqz.wordpress.com/2014/02/11/you-got-tenure-now-what/ http://xykademiqz.wordpress.com/2014/02/08/tenure-track-illustrated/ Maria Klawe, president of Harvey Mudd College, has a good, short article on her own experiences with impostor syndrome in Slate. For a somewhat younger perspective, Alicia Liu’s article Overcoming Imposter Syndrome is worth reading. Incidentally, there is a flip side to the problem, of students (often, but not exclusively, male students from privileged backgrounds) having too much confidence and not being aware when they are out of their depth, failing to ask for help when they need it. Both problems can be tackled with the same approach: seeking outside verification of your abilities and paying attention to the feedback. This is easiest while being a student, as there are many formal mechanisms in place for honest feedback—it gets harder when you have to rely on the more random mechanisms of journal paper reviews and grant proposals or pats on the back from co-workers. As a community, we can all help with both problems by providing honest feedback (neither ego strokes nor unwarranted criticism) when asked for it, and by asking for feedback ourselves. For my part, I tend to see the negative both in my own work and in others’ work, and I am working on trying to increase the amount of positive feedback I give people. 2014 July 7 Crowdfunding for UCSC iGEM project Filed under: Uncategorized — gasstationwithoutpumps @ 19:34 Tags: , , , , , The UCSC undergraduate team for the iGEM synthetic biology competition have put up a crowd-funding web site to try to raise the money they need for their contest entry. https://experiment.com/projects/sustainable-next-generation-biofuel-production Their design project is to engineer a bacterial strain for cellulosic alcohol production—not ethanol, but butanol, whose energy density is more compatible with the existing gasoline infrastructure and that does not absorb so much water. Conventional ways of creating butanol are too expensive, so recombinant bacteria are a promising approach. Using cellulose as a feedstock avoids competing with food production, as waste paper and other non-food sources can be used. They are not trying to do everything at once—they are working this summer on getting butanol production from glucose engineered into Haloferax volcanii, a halophile that their mentor has worked with a fair amount. I’m not sure what their reasoning is for using a halophile—perhaps they just wanted to work in an archeon, and H. volcanii is one of the best-established model organisms for Archaea. Their mentor for the project is donating his time, so all the costs are unavoidable reagent, equipment time, or registration fee costs. The team description (including membership) is at http://igem.org/Team.cgi?id=1560, and the wiki where you can follow their progress is at http://2014.igem.org/Team:UCSC (though they’ve nothing there yet but an introduction to the project). I gave a token amount, and I urge others to do so also (or more if you are feeling generous). They’re currently about halfway to their goal. https://experiment.com/projects/sustainable-next-generation-biofuel-production 2014 July 6 Battery connectors Filed under: Uncategorized — gasstationwithoutpumps @ 02:32 Tags: , , , , , , , , I spent a little time today working on my book, but I got side tracked into a different project for the day: designing a super-cheap coin-cell battery connector. I’ve used coin-cell battery holders before, like on the blinky EKG board, where I used a BH800S for 2 20mm CR2032 lithium cells. That battery holder is fairly large and costs over$1—even in 1000s it costs 70¢ a piece. So I was trying to come up with a way to make a dirt cheap coin-cell holder.

The inspiration came from the little LED lights that “glovers” use inside their gloves. They are powered by two CR1620 batteries (that means a 16mm diameter and 2.0mm thickness for the battery). Because the lights have to be made very cheaply, they don’t use an expensive holder, but put the negative side of the batteries directly against a large copper pad on the PC board. The batteries are held in place by the positive contact, which is a piece of springy metal pressing the battery against the board—and each manufacturer seems to have a slightly different variant on how the clip is made.

Unfortunately, I was unable to find any suppliers who sold the little clips—though I found several companies that make battery contacts, it seems that most are custom orders.

My first thought was to bend a little clip out of some stainless steel wire I have sitting around (not the 1/8″ welding rod, but 18-gauge 1.02362mm wire). That’s about the same thickness as a paperclip (which is made out of either 18-gauge or 19-gauge wire), but the stainless steel is stiffer and less fatigue-prone than paperclips. I was a little worried about whether stainless steel was solderable, so I looked it up on Wikipedia, which has an article of solderability. Sure enough, stainless steel is very hard to solder (the chromium oxides have to be removed, and that takes some really nasty fluxes that you don’t want near your electronics). So scratch that idea.

I spent some time looking around the web at what materials do get used for battery contacts—it seems there are three main ones: music wire, phosphor bronze, and beryllium copper, roughly in order of price. Music wire is steel wire, which gets nickel plated for making electrical connections. It is cheap, stiff, and easily formed, but its conductivity is not so great, though the nickel plating helps with that. The nickel oxides that form require a sliding contact to scrape off to make good electrical connection. Phosphor bronze is a better conductor, but may need plating to avoid galvanic corrosion with the nickel-plated battery surfaces. Most of the contacts I saw on the glover lights seemed to have been stamped out of phosphor bronze. Beryllium copper is a premium material (used in military and medical devices), as it has a really good ratio of yield strength to Young’s modulus, so it can be cycled many times without failing, but also has good conductivity.

Since I don’t have metal stamping machinery in my house, but I do have pliers and vise-grips, I decided to see if I could design a clip out of wire. It is possible to order small quantities of nickel-plated music wire on the web. For example, pianoparts.com sells several different sizes, from 0.1524mm diameter to 0.6604mm diameter. I may even be able to get some locally at a music store.

My first design was entirely seat-of-the-pants guessing:

First clip design, using 19-gauge wire, with two 1mm holes in PC board to accept the wire. This design is intended for two CR1620 batteries.

The idea was to have a large sliding contact that made it fairly easy to slide the batteries in, but then held them snugly. Having a rounded contact on the clip avoids scratching the batteries but can (I hope) provide a fair amount of normal force to hold the batteries in place. But how much force is needed?

I had a very hard time finding specifications on how hard batteries should be held by their contacts. Eventually I found a data sheet for a coin battery holder that specified “Spring pressure: 50g min. initial contact force at positive and negative terminals”. Aside from referring to force as pressure and then using units of mass, this data sheet gave me a clear indication that I wanted at least 0.5N of force on my contacts.

I found another battery holder manufacturer that gave a tiny graph in one of their advertising blurbs that showed a range of 100g–250g (again using units of mass). This suggests 1N-2.5N of contact force.

Another way of getting at the force needed is to look at how much friction is needed to hold the batteries in place and what the coefficient of friction is for nickel-on-nickel sliding. The most violently I would shake something is how fast I can shake my fingertips with a loose wrist—about 4Hz with an peak-to-peak amplitude of 22cm, which would be a peak acceleration of about 70 m/s^2. Two CR1620 cells weigh about 2.5±0.1g (based on different estimates from the web), so the force they need to resist is only about 0.2N. Nickel-on-nickel friction can have a coefficient as low as 0.53 (from the Engineering Toolbox), so I’d want a normal force of at least 0.4N. That’s in the same ballpark as the information I got from the battery holder specs.

So how stiff does the wire have to be? I specified a 0.2mm deflection, so I’d need at least 2N/mm as the spring constant for the contact, and I might want as high as 10N/mm for a really firm hold on the batteries.

So how should I compute the stiffness of the contact? I’ve never done mechanical engineering, and never had a statics class, but I can Google formulas like any one else—I found a formula for the bending of a cantilever loaded at the end:
$\frac{F}{d} = \frac{3 E I}{L^{3}}$, where F is force, d is deflection, E is Young’s modulus, I is “area moment of inertia”, and L is the length of the beam. More Googling got me the area moment of inertia of a circular beam of radius r as $\frac{\pi}{4} r^{4}$. So if I use the 0.912mm wire with an 8mm beam I have
F/d = 200E-6 mm E.

More Googling got me some typical values of Young’s modulus:

material E [MPa = N/(mm)^2]
phosphor bronze 120E3
beryllium copper 135E3
music wire 207E3

If I used 19-gauge phosphor bronze, I’d have about 24N/mm, which is way more than my highest desired value of 10N/mm. Working backwards from 2–10N/mm what wire gauge would I need? I get a diameter of 0.403mm to 0.603mm, which would be #6 (0.4064mm), #7 (0.4572mm), #8 (0.5080mm), #9 (0.5588mm), or #10 (0.6096mm), on the pianoparts.com site. I noticed that battery contact maker in Georgia claims to stock 0.5mm and 0.6mm music wire for making battery contacts, though they first give the sizes as 0.020″ and 0.024″, so I think that these are actually 0.5080mm and 0.6096mm (#8 and #10) music wire.

It seems that using #8 (0.020″, 0.5080mm) nickel-plated music wire would be an appropriate material for making the contacts. Note that the loop design actually results in two cantilevers, each with a stiffness of about 4N/mm, resulting in a retention force of about 1.6N. The design could be tweaked to get different contact forces, by changing how much deflection is needed to accommodate the batteries.

How much tweaking might be needed?  I found the official specs for battery sizes (with tolerances) in IEC standard 60086 part 2: The thickness for a 1620 is 1.8mm–2mm, the diameter is 15.7mm–16mm, and the negative contact must be at least 5mm in diameter.  The standard also calls for them to take an average of 675 hours to discharge down to 2v through a 30kΩ resistor (that’s about 56mAH, if the voltage drops linearly, 67mAH if the voltage drops suddenly at the end of the discharge time).  If the batteries can legally be as thin as 1.8mm, then to get a displacement of 0.2mm, I’d need the zero-point for the contacts to be only 3.4mm from the PC board, not 3.8mm, and full thickness batteries would provide a displacement of 0.6mm, and a retention force of about 4.8N.

If I were to do a clip for a single CR2032 battery, I’d need to have a zero-point 2.8mm from the board, to provide 0.2mm of displacement for the minimum 3.0mm battery thickness.

So now all I need to do is get some music wire and see if I can bend it by hand precisely enough to make prototype clips.  I’d probably change the spacing between the holes to be 0.3″ (7.62mm), so that I could test the clip on one of my existing PC boards.

Update 2014 July 6: I need to put an insulator on the verticals (heat shrink tubing?), or the top battery will be shorted out, since the side of the lower battery is exposed.

2014 July 3

Digital filters: infinite-impulse-response filters

Filed under: Uncategorized — gasstationwithoutpumps @ 17:13
Tags: , , , , , ,

Yesterday I wrote a very brief introduction to z-transforms and finite-impulse-response filters.  Today I’ll try to do infinite-impulse-response (IIR) filters.  Obviously, one blog post can’t do justice to the topic, but I’ll try to get far enough that my son can implement some simple filters for his project.  If he needs more detail, the tutorial at CCRMA by Julius Smith is probably worth reading.

The basic idea of an IIR filter is that the transfer function is not a polynomial but a rational function.  For example, the standard “biquad” digital filter unit is the ratio of two quadratic formulas: $H(z) = \frac{b_{0} + b_{1}z^{-1} + b_{2}z^{-2}}{1 + a_{1}z^{-1} + a_{2}z^{-2}}$.

There are a lot of different ways to implement the biquad section, trading off various properties, but one that has particularly nice numeric properties is the “direct form I” implementation.

Direct form I for implementing a biquad filter section. Taken from https://ccrma.stanford.edu/~jos/filters/Direct_Form_I.html

The transfer function can be checked by looking at the summation in the center and taking z-transforms: $Y(z) = X(z)(b_{0} + b_{1}z^{-1} + b_{2}z^{-2}) - Y(z)(a_{1}z^{-1} + a_{2}z^{-2})$, followed by simple algebra to rearrange to get the transfer function above. One nice property of this particular implementation for fixed-point computation is that as long as the output stays within range, there are no problems with overflow in intermediate computations.

The left half of the implementation computes the numerator of the transfer function, which may have either two real zeros or a conjugate pair of complex ones (or a single real zero, if b2=0).  It is often useful to look at these zeros in polar form, $Ae^{i\theta}$, since the resulting filter will have minima at $\omega=\theta$, and how sharp the minimum is depends on how close A gets to 1. One popular choice for bandpass filters is to put the zeros at 1 and –1, so that there are zeroes at DC (ω=0) and at the Nyquist frequency (ω=π), which gives $1-z^{-2}$ as the numerator. For a low-pass filter, both zeros are often put at the Nyquist frequency, giving $(1+z^{-1})^2$, while for a high-pass filter, both zeros are often put at DC, giving $(1-z^{-1})^2$.

The right half of the implementation computes the denominator of the transfer function producing a pair of poles, and it is again useful to look at the poles in polar form. For stability of the filter we need to have the poles within the unit circle— even getting them too close to the unit circle can cause the output to get very large and cause numeric overflow.

Note that any rational function with real coefficients can be factored into biquad units with real coefficients, just by factoring the polynomials into a product of roots, and pairing the complex roots in their conjugate pairs. Because the direct implementation of a high degree polynomial is very sensitive to rounding errors in the parameters, it is common to factor the transfer function into biquad units.

About a year ago, I was playing with a biquad filter for an optical pulse monitor, where I wanted a roughly 0.4—2.5 Hz bandpass filter, with a sampling rate of 30Hz, using only small integer coefficients. I put the zeros at 1 and —1, and used a filter-design site on the web to get real-valued coefficients for the denominator. I then approximated the real-valued coefficients as integers divided by powers of two, and tried tweaking the coefficients up and down to get close to the response I wanted, using gnuplot to plot the gain:

Biquad design for a bandpass filter with peak around ω=π/15 using only small integer coefficients.

The code I used for implementing the biquad bandpass filter on a microcontroller was fairly simple:

     y_0 = b0*(x_0-x_2) - a1*y_1 -a2*y_2;
Output(y_0);
x_2 = x_1;
x_1 = x_0;
y_2 = y_1;
y_1 = y_0/a0;


Note that I’m outputting the high-precision output from the summation node, which has an extra gain of a0. The memory elements (x_1, x_2, y_1, y_2) have the same precision as the input—only the summation is done at higher precision. The division in the last line is not really a division but a shift, since I restricted a0 to be a power of 2. This shifting could be done after the multiplications of y_1 and y_2 in the first line, if y_1 and y_2 are carried to higher precision, but then the intermediate results in the summation could get too large—a lot depends on how big the word size is compared to the input values and the a0 scaling.

My son is probably interested in two digital filters—one to remove the DC bias (so a high-pass with cutoff frequency around 10–20Hz) and one to pick out the beat from a non-linearly modified signal (absolute value or squared signal). The beat he is interested in picking out is probably around 60–180bpm or 1–3Hz—similar to what I did for picking out heartbeats (I used 0.4—2.5Hz as a rough design goal on the pulse monitor). Unfortunately, as you go to higher sampling frequencies, you need to have higher precision in the filter coefficients.

The biquad coefficient calculator at http://www.earlevel.com/main/2013/10/13/biquad-calculator-v2/ seems pretty good, though it is a bit tedious to rescale and round the coefficients, then check the result. So I wrote a Python script to use the scipy.signal.iirfilter function to design filters, then scaled and rounded the coefficients. The scaling factor had to get much larger as the sampling frequency went up to get a good bandpass filter near 1Hz, otherwise rounding errors resulted in a low-pass filter rather than a bandpass filter (perhaps one of the poles ended up at 1 rather than as a complex pair?). To make a 0.33–3Hz bandpass filter, I needed to scale by 230 at 40kHz, 221 at 10kHz, 216 at 3kHz, 215 at 1kHz, 211 at 300Hz, and 28 at 100Hz. The scaling factors needed for 40kHz sampling would exceed the 32-bit word size, so this approach did not look very promising.

It may be more effective to use two separate biquad sections: a low-pass filter with a fairly high cutoff to downsample the signal, then a bandpass filter at the lower sampling rate. This approach allows using much lower-precision computations. I wrote a little Python program to test this approach also, aiming for a 0.33–3Hz bandpass filter.

Here is the filter response of a low-pass filter, followed by down-sampling and a bandpass filter. Note that the scaling factor is only 214, but the filter response is quite nice.

So the overall design of the loudness sensor will probably be a series of filters:

• high-pass filter at 20Hz to remove DC bias, leaving sound
• nonlinear operation (squaring or absolute value)
• low-pass filter at 200Hz
• down-sample to 500Hz
• bandpass filter at 0.33–3Hz

One possible problem with this approach—look at the phase change when the beat is not 1Hz. At 0.33Hz, the phase change is about 37º, which is about 0.3s—a larger shift in the beat than we’d want to see. We may have to look at more complicated filter design that has smaller phase shifts. (The -49º phase shift at 3Hz is only about 45msec, and so not a perceptual problem.)

Here is a possible filter design for the initial high-pass filter:

Getting a 20Hz cutoff frequency required a somewhat larger scaling factor than for the other filters, but still quite reasonable for 14-bit values on a 32-bit machine.

Here is a version of the two-stage filter design program:

#!/usr/bin/env python

from __future__ import division,print_function

import numpy as np
import scipy
from scipy.signal import iirfilter,freqz,lfilter,tf2zpk
import matplotlib.pyplot as plt

pi=3.1415926535897932384627

fs = 40.e3  # sampling frequency

low_fs = 1000.  # sampling frequency after downsampling
cutoffs = (0.33,3.0)  # cutoff frequencies for bandpass filter in Hz

scale_factor = 2.**14

def scaled(b,a):
"""scaled b and a by scale_factor and round to integers.
Temporarily increase scale factor so that b[0] remains positive.
"""
extra_scale=1.
b_scaled = [int(np.round(scale_factor*c*extra_scale)) for c in b]
while b_scaled[0]==0:
b_scaled = [int(np.round(scale_factor*c*extra_scale)) for c in b]
extra_scale *= 2
a_scaled = [int(round(scale_factor*c*extra_scale)) for c in a]

print (" b=",b, "a=",a)
z,p,k = tf2zpk(b,a)
print ( "zeros=",z, "poles=",p, "gain=",k)

print ("scaled: b=",b_scaled, "a=",a_scaled)
z,p,k = tf2zpk(b_scaled,a_scaled)
print ( "zeros=",z, "poles=",p, "gain=",k)

return b_scaled,a_scaled

def plot(b1,a1, b2,a2, frequencies=None):
"""Plot the gain (in dB) and the phase change of the
concatentation of filters sepecified by b1,a1 and b2,a2.

The b1,a1 filter is designed to run at sampling rate fs

The b2,a2 filter is designed to run at sampling rate low_fs

Both are designed with the filter type specified in global filter.
"""

if frequencies is None:
worN =[pi*10.**(k/200.) for k in range(-1000,0)]
else:
worN = [2*pi*f/fs for f in frequencies]

freq,response1 = freqz(b1,a1, worN=worN)
freq2,response2 = freqz(b2,a2, worN=[f*fs/low_fs for f in worN])
freq *= fs/(2*pi)

response = response1*response2

fig=plt.figure()
plt.title ('{}: b1={} a1={} fs={}\n b2={} a2={} fs={}'.format(filter,b1,a1,fs,b2,a2,low_fs))

plt.semilogx(freq,20*np.log10(np.abs(response)), 'b')
plt.ylabel('Amplitude [dB]', color='b')
plt.grid()
plt.legend()
plt.xlabel('Frequency [Hz]')

ax2 = ax1.twinx()
angles = [ 180/pi*ang for ang in np.unwrap(np.angle(response)) ]
plt.plot(freq,angles, 'g')
plt.ylabel('Phase change [degrees]', color='g')
plt.show()

for low_fs in [100., 200., 400., 500., 800., 1000., 2000.]:
filter='bessel'
low_cut = 0.4*low_fs
b1,a1 = iirfilter(2, low_cut/fs, btype='lowpass', ftype=filter, rp=0.1, rs=0.1)
print (filter, "lowpass for fs=",fs, "cutoff=", low_cut)
b1_scaled,a1_scaled = scaled(b1,a1)

b2,a2 = iirfilter(1, [2*f/low_fs for f in cutoffs], btype='bandpass', ftype=filter, rp=0.1, rs=0.1)
print(filter, "bandpass for fs=", low_fs, "cutoffs=",cutoffs)
b2_scaled,a2_scaled = scaled(b2,a2)

plot(b1_scaled, a1_scaled, b2_scaled, a2_scaled, [10.**(k/200.) for k in range(-400,min(401,int(200.*np.log10(low_fs/2))))])

« Previous PageNext Page »