Gas station without pumps

2017 August 20

Santa Cruz Shakespeare 2017 reviews

In More recent theater events, I listed the 8 plays I’d seen in May and June, and reviewed Santa Cruz Shakespeare’s production of The 39 Steps.  Since then, I’ve seen the rest of the Santa Cruz Shakespeare season and a couple of other performances

Date title produced by
2017 July 18 Antony and Cleopatra Royal Shakespeare Company (broadcast)
2017 July 28 Measure for Measure Santa Cruz Shakespeare
2017 Aug 5 Split the Bill
2017 Aug 8 A Most Dangerous Woman (staged reading) Santa Cruz Shakespeare
2017 Aug 11 Shakespeare Conservatory showcase West Performing Arts
2017 Aug 15 The Night that Never Existed (staged reading) Santa Cruz Shakespeare
2017 Aug 19 Two Gentlemen of Verona Santa Cruz Shakespeare

Let me start with the non-SCS performances.

I won’t bother reviewing the Royal Shakespeare Company performance—it was worth seeing, but did not wow me. A workman-like production with nothing to excite particular interest.

Split the Bill was a combination of sketch comedy and improv with many of the same actors who were in the Dinosaur Prom improv troupe that my son used to act with, plus some younger comedians.  I suspect that he could have been in the Split the Bill shows if he had gone to the earlier ones this summer (this was their fourth of four), but his sleep-all-day schedule this summer has made it difficult for him to do anything involving other people.  The show was similar in quality to the Dinosaur Prom shows—amusing in the moment, but not particularly memorable.

The West Conservatory showcase was a little different from previous years, in part because they had different teachers this year.  The monologues and scene work were quite good, but the choral piece at the beginning was ragged and the clowning towards the end a bit clumsy. There are several upcoming actors in the WEST troupe who are good, so we’ll probably continue to go to the WEST teen shows, even though our son has aged out.  (Perhaps I should say “actresses” instead of “actors”, since only one of the actors in the conservatory was male, but I tend to use “actor” as a genderless designation.)

For transportation to the four Santa Cruz Shakespeare productions at the Audrey Stanley Grove, we did bus+walk to get to Measure for Measure, but walked the whole way (about 3.8 miles) for the other three productions.  For all of them we took Lyft home.  The walk takes us about 1:25, so is about the same speed as walking plus bus.  Lyft continues to be a fairly reliable way to get home (better than the taxicabs we tried last year).

The Measure for Measure production was the weakest one of SCS’s 2017 season.  Although there was some good individual acting, overall the performance was run of the mill.  The lower-cast characters were so ruthlessly cut that they added little to the play, the costuming looked like a low-budget high-school production, and the direction was lackluster.  They were deliberately working with a small cast so that the production could move to CalShakes after finishing in Santa Cruz, but the double and triple casting was not very effective.  In particular, I found that double casting Claudio and Pompey (and clothing both in the same prison outfit distinguished only by Pompey’s hat) did not work well.  I also did not care for dressing Angelo in high boots—it would have been better to dress him as a missionary than as a Nazi. The directorial choice of handling the problematic ending by converting the Duke’s marriage proposal into a job offer (with no changes to the lines) was reasonable for a 21st century audience, but it seems like so much of the director’s effort went into that choice that there was no time to make the rest of the play work well.

The two staged readings were an interesting experiment on SCS’s part.  They were expecting a fairly small turnout, but got around 200 for each of the readings. I don’t have cast lists for the two performance, though I recognized a number of the performers.  Julie James did a good job as George Eliot in A Most Dangerous Woman (by Cathy Tempelsman), and Mike Ryan was good in both shows.  I was expecting a little more blocking and gesturing in the performances, but quickly adjusted to the style of actors stepping up to the music stands with their scripts to indicate when they were on stage.  The story of George Eliot’s life made a good play, and it would be a good one for Jewel Theatre to produce (a better part for Julie James than many of the ones she casts herself in).

The Night that Never Existed is a play by Humberto Robles, translated from Spanish by Rochelle Trotter. It is a two-hander, with Mike Ryan playing Shakespeare and Patty Gallagher playing Queen Elizabeth.  The concept is a simple one: Queen Elizabeth asks Shakespeare to teach her about love.  Many of the lines are borrowed from Shakespeare’s plays and sonnets and are deftly arranged to support the scenes. Unfortunately, there are also a number of expository lines (Queen Elizabeth praising Shakespeare) that are leaden—I don’t know whether the fault here belongs to Robles, Trotter, or both.  It would require a really fine production by virtuoso performers to make this play worth producing, though with a little editing it could work well.

Overall, the staged readings were a good experiment, providing dedicated theater goers some extra entertainment and allowing the company to experiment with some different plays that probably could not command a big enough audience for a full production.  One big problem was the sound.  I was unable to hear one of the actresses in A Most Dangerous Woman (I don’t know her name), and even Patty Gallagher was hard to hear from the third row in The Night that Never Existed. I had no trouble hearing Patty in her roles in the main productions, so I think that the problem was more lack of rehearsal than inherent to the actresses.  The outdoor stage at the Grove does require more projection than most actors are used to, and it is particularly hard for the higher-pitched female voices (and it doesn’t help that I’m going deaf, losing the higher frequencies first). The sound system doesn’t help much, as it introduces echoes before it provides much support.  Perhaps the sound engineers could work on better speaker and mic placement for next year, and perhaps some filtering to produce more treble than bass boost.

Two Gentlemen of Verona is probably the best show this summer, though it is a toss-up with The 39 Steps. The costuming for Two Gents is some of the best I’ve seen from B. Modern (who is a great costume designer), directing was inspired, and the clowns Launce and Speed given full rein (they are too often cut drastically or underplayed).  This production was much better than the 1999 production by Shakespeare Santa Cruz (I still remember being disappointed that they had cut Launce’s “my cane understands me” joke in that production).  The conversion of Launce from a male to a female role worked surprisingly well, even if it did substantially change the sexual jokes in the milkmaid (changed to milkman) scene.  Doing that scene as a cabaret act was really impressive and gave the acting interns a chance to show off some of their skills. All the acting in this play was great (well, one muffed line by Speed, but it did not detract from his otherwise good performance).

Unlike Measure for Measure, the company did not come up with a reasonable resolution for the abrupt ending of Two Gents (the forgiveness for Proteus still seems wholly unnatural), but the rest of the play was so good that one could forgive them for not being able to fix Shakespeare’s clumsiness here.

Bottom line: go to see The 39 Steps and Two Gentlemen of Verona.  If you have time for a third play, Measure for Measure is ok.  If you can only afford the time for one play, choosing between The 39 Steps and Two Gentlemen of Verona is tough—you are unlikely to have an opportunity to see a better production of either play.  Much of the humor of The 39 Steps relies on the differences between film and stage productions (and it helps to have seen the movie—indeed to have seen several Hitchcock movies), while Two Gentlemen of Verona is a comedy that is intended to stand on its own.

Futuristic Lights’ new product: Ion C2C

Filed under: Uncategorized — gasstationwithoutpumps @ 11:35
Tags: ,

The Kickstarter for fidget spinners didn’t succeed, so Futuristic Lights decided that they’d missed the market for high-end fidget spinners and decided to stick with their strengths in gloving lights.  Their newest product is an entry-level gloving set, the Ion C2C, which is priced at $40 a set (only $35 during preorders). The lights are quite featureful for that price point, comparable to or better than $80 sets from their competitors.  Here are their claims from their sales page (go there to see videos of Ion C2C and more information):

With every new glove set we make, Futuristic Lights pushes the boundaries of what’s possible. The Ion is no exception! We think every Glover should have access to the latest gloving technology we offer, regardless if you’re a beginner or pro. To make this a reality, we had to make sure the Ions are as affordable as possible.

So … What do the Ions do?

The answer is …   More than every other entry level burner set combined!

Entry level lights tend to be affordable, but you don’t get very many features or modes. We wanted to change this. So instead of making just a streamlined version of our other lights, we made something completely unique. We’ve even added some new features that not even our top-of-the-line products have. 


  • Chip to Chip Communication 1.0 (C2C)
  • Randomizer
  • 38 Colors
  • 8 Flashing Patterns (Modes)
  • 8 Colors Per Mode
  • Demo Loop
  • True Brightness Control
  • Battery Lock
  • Conjure Mode (Updated)
  • Demo View
  • Factory Reset
  • And to top it off, it’s the same nano size as the Atoms!

I think that this product will pull some sales away from their more expensive lines as it offers a lot of the features much cheaper, but their hope is that it will pull even more sales away from their competitors.  Despite Futuristic Lights’ small size and tiny market share, they have managed through good engineering and good manufacturing contracts to keep their costs low, so that they can offer a high-end product at a low cost.  Their minimum orders for the manufacturing contracts are fairly high, though, so they are going to have to sell a lot to break even.

Because the gloving market is one that they are already familiar with (unlike the fidget spinners), they are not testing the waters with a Kickstarter campaign, but going directly to manufacturing.  They expect to be able to ship in about a month—assuming that no major problems crop up in the final testing of the firmware being done now.

2017 August 19

Progress on my book

Filed under: Circuits course — gasstationwithoutpumps @ 16:05
Tags: , ,

I have been slogging through the book, updating it to include feedback I got on it from students and notes I had made on grading assignments, and revising the labs to use the Analog Discovery 2 rather than conventional bench equipment.

I was a little disheartened when I noticed that I’ve just finished updating through Lab 3, out of the 12 labs. That looks like I’m only a quarter of the way through the rewrite, when I had hoped to be almost halfway by now. When I look at it in terms of pages, though, I’m much further along—I’ve revised through page 142, and there are 360 numbered pages before the references (not counting the 37 Roman-numeral pages), so I’m about 40% of the way through the rewrite. That’s a little behind schedule, but not terrifyingly so, especially since it is the beginning labs that needed the most changes to convert to using the Analog Discovery 2.

There are still 132 to-do notes scattered through the book, some of which are in sections I’ve counted as “done” for the summer, so I’m not going to run out of work on the book any time soon.

The PDF file is currently at 411 total pages, with 179 figures (203 distinct images, as there are some figures with subfigures) and 13 tables. It is up to 22.8Mbytes, which I could probably reduce by a few MBytes by better compression of some of the JPEG figures.

I’ve previously thought that it would be good to be able to make paper copies of the book available to students (see Textbook should be on paper), but the print-on-demand services seemed too expensive.  I was apparently not looking at reasonable services, as IngramSpark’s “print-and-ship” calculator says I can now get a single copy (perfectbound paperback, standard color, simplex cover) for about $24 (including shipping and sales tax).  Ordering 50–100 copies doesn’t reduce the price much (still $20 a copy—all the reduction is in shipping).  Unfortunately, their “weight and spine width” calculator says that my page length is out of range for an 8.5″×11″ book, but if I reduce my trim size slightly (t0 8.25″×10.75″), I can print with them and the cost is about a dollar more.  (There may also be an initial setup charge to create the book the first time, including things like getting an ISBN.)

If the book gets much fatter, I’d have to switch to a smaller trim size, which would make the book fatter still, and the increase in the number of pages would increase the cost.  I think that a 7″×10″ trim (which would allow up to 1140 pages) would cost about $3.50 more than an 8.5″×11″ book for the same content, assuming that I reduced the margins and the text block, but didn’t change font sizes.

Paper books through distribution channels are expensive: to get $4 a book (about what I get from the $5 e-book sales through Leanpub), I’d have to have a list price of about $42 a book based on IngramSpark’s publisher’s compensation calculator.

2017 August 15

Beacon detector SPI interface

Filed under: Uncategorized — gasstationwithoutpumps @ 12:53
Tags: , , ,

In Beacon detector board, I introduced the hardware for the IR beacon detector, and in Digital tone detection with Goertzel’s algorithm, I discussed the algorithm used for detecting a 2kHz signal in a noisy background.  In this post I’ll talk about the software for interfacing the board to microcontrollers as if it were a standard peripheral device.

When I was designing the hardware, I had to choose between providing a UART interface, an SPI interface, or an I2C interface. At one point, I considered including all three, since I had just enough pins to do that and plenty of board space for connectors.

My son urged me to use a UART interface, since asynchronous communication is much easier work with than the two synchronous interfaces—there are no tight timing constraints. UART communications tends to be slow (115200 baud is a common top speed, resulting in a maximum of about 11.5–12.8kbytes/second transferred), and the two sides must agree on the baud rate to within 2.5%. But there are no latency constraints—you can respond to a request whenever you are finally ready—so there are no worries if you need to wait for a timer task to complete before communicating. The main downside of a UART interface (besides the usually low speed) is that it is a one-to-one interface. Two pins are needed for each UART a microcontroller uses, while the synchronous interfaces provide shared bus communication.

I knew that I could do a UART interface and for the small amounts of data I needed to communicate (10–75 bytes every 60th of a second, or 600–4500 bytes/s) it would be fast enough. But I wanted a challenge that would help me learn something new, so I decided to do a synchronous interface. Of the two choices supported by the Teensy LC hardware, SPI and I2C, the SPI interface looked the simpler to implement in software, as the timing seemed a little less challenging, and there was a FIFO that could be loaded with several bytes of information to transfer, reducing the timing demands. (In retrospect, I2C may have been easier—I’ve not tried it, though, so there may be some unexpected challenges.)

I created the board with only one I/O port (other than the USB port used for programming the board), the SPI0 4-wire interface using pins CS=D10=PTC4, MOSI=D11=PTC6, MISO=D12=PTC7, SCK=D13=PTC5.  I used a 6-pin right-angle header at the edge of the board, so that I would be able to use a ribbon connector to connect to another microcontroller. The order of the pins is the same as Digilent uses for their PMOD connector—an arbitrary choice, but there does not seem to be a commonly accepted standard for SPI connections.

The choice of pins was the first mistake I made in the SPI design—I should have used SPI1 instead of SPI0.  In reading the reference manual for the KL26 chip that is the basis for the Teensy LC, the SPI FIFO is only implemented for SPI1, and not for SPI0.  Also, the legal SPI clock speeds are different for the two interfaces:  SPI0 is clocked off the bus clock (default 24MHz on the Teensy LC) and SPI1 off the system clock (default 48MHz). The external clock SCK is allowed to go from 0Hz to ¼ the module clock, so 6MHz for SPI0 and 12MHz for SPI1.

The lack of a FIFO on SPI0 made the timing for loading the transmit buffer a little tricky.  The hardware has two registers for the transmit: the shift register used for serializing a byte and the transmit buffer that holds the next byte to transfer to the serial register.  If the transmit buffer is not loaded in time for the serial shifting, then the SPI interface will duplicate the previous byte, messing up communication.

The Teensyduino library contains SPI master software, but not SPI slave software.  I was wondering about the reason for that before I started my coding, but I quickly realized why—the timing for SPI is almost entirely under control of the master and the slave is constrained to respond at times specified by the master.  The most common SPI protocols for peripherals consist of the master sending a 1-byte (or longer) command to the slave and getting a response back in the next byte slot(s).  This gives the slave about half a clock period to interpret the command and prepare the response. With a 1MHz SCK, that gives the processor about 500ns to set up the response. That’s plenty of time for an all-hardware system, but is a very tight constraint for a software implementation.  In fact, given that the interrupt latency on the KL26 can be about 800ns, it is an impossible constraint—I don’t even know that I need to send a byte, much less figure out what it is, in the available time.  The more complicated I2C interface allows a slave to stretch out the clock when it can’t respond in time, but the SPI interface doesn’t allow the slave to change the clock rate.

So I couldn’t use the most common SPI interface protocol of command followed by immediate response. I had a few choices of workarounds for the latency problem:

  • Have a standardized packet of material that is sent independent of what the master does.  This seems to be the solution used by SPI slave libraries others have written for the Teensy boards (not part of the standard Teensyduino library).  It allows high throughput, especially if DMA is used to load the transmit information, but is not very flexible.  It is not a commonly used protocol on SPI peripherals.
  • Require the master to wait before asking for the response bytes.  This is very flexible and allows the SPI bus to run at maximum speed during transfers, but is not really in the spirit of a synchronous interface—the slave should respond at a standardized time, and the master should not have to know how long it will take the slave to be ready to send.
  • Send a dummy byte in the slot after the request so that I have a full byte time (8 SCK periods) instead of half a bit time to get the right information ready. A disadvantage is that the throughput is reduced—the dummy bytes take up bus time without communicating useful information. If the protocol calls for a 1-byte command and a 1-byte response, then each transfer would take 3 byte times.  (A 1-byte command and an n-byte response takes n+2 byte times.)

I ended up using a slight variant of the dummy-byte approach: I allow the master to send new commands before the first response comes back.  Dummy bytes are only added when there are no real bytes to send, so a series of n commands requesting 1-byte responses could be sent in a row, with the total time for the transfer taking n+2 byte times—the first two slots of which the slave is sending dummy bytes, and the next n are the requested data.

To make this protocol work, I had to ensure that the SPI interrupt priority is higher than any other interrupts in the program, in particular, higher than the PIT timer that I was using for the 15kHz sampling frequency.  This means that the SPI transmissions will introduce jitter into the ADC sampling—I’ve not yet determined how much of a problem this will be, but I suspect it won’t be much of a problem, since it will only affect one or two samples in the 250-sample filter block.  The default interrupt priority on the KL26 processor in the Teensy LC is for all interrupts to be at the highest priority, so I had to lower the PIT priority rather than raising the SPI priority.

The basic notion is that I keep the SPI transmit buffer always full.  When there is a transmit-buffer-empty interrupt, I load the buffer from a software FIFO I maintain, or with a dummy byte (0xff) if there is nothing in the FIFO.  The responses to a command are loaded into the FIFO.  As long as the SPI interrupt response (including interpreting the command and any FIFO loading or popping) takes less than the time of one byte, the protocol runs smoothly.  With commands that can send up to 4-byte responses, I was able to run SCK up 1.25MHz without losing synchronization.

My current, minimal command set for the beacon detector has the following commands:

  1. Freeze the information from filter so that all subsequent commands refer to the same set of data.  Return 1 on success, 0 on failure.  (The failure is only possible if the request is sent too soon after a reset of the beacon detector board.)
  2. Report which channel has the highest power (1-byte: 0xff if no beacon detected, otherwise 0..7)
  3. Report the estimated angle of the beacon in 0.1° units (2-bytes: 0..3599)
  4. Report the power in the max-power channel (4-bytes: unsigned int)

I could also report the power in specific channels and the power from an alternative (3kHz instead of 2kHz) filter for each channel, which would be another 64 bytes of information, but I’ve not implemented those commands yet.  The minimal set I currently have responds with 8 bytes of information, so takes 10 byte times for a burst of communication. With the highest clock rate I’ve gotten to work (SCK=1.25MHz), a full packet takes 64µs, which would interfere with only one or two samples of the 15kHz sampling.

I may play around with different command sets after I get another board programmed as a master to communicate with the beacon detector and determine what information I really need from the beacon detector.  One possibility is to use just a single 2-byte response that encodes everything but the power: that would allow a 4-byte-time packet (25.6 µs).

Setting up the SPI software ran into all the usual problems with setting up a peripheral on a Kinetis ARM processor—there are many registers that need to be set up correctly, and nothing works until they are all right:

  • Turn on the SPI module clock: SIM_SCGC4 |= SIM_SCGC4_SPI0
  • Set the SPI control registers SPI0_C1 and SPI0_C2 for 4-wire SPI with CPOL=1, CPHA=1, 8-bit mode, interrupt on receiving a byte or on transmit buffer empty.
  • Set up the isr to interpret the recieved bytes and keep the transmit buffer full.                                           
  • Configure the 4 pins used to be ALT 2 (SPI0) rather than the default GPIO.
  • Set the priorities using NVIC_SET_PRIORITY(IRQ_SPI0, 0) and NVIC_SET_PRIORITY(IRQ_PIT_CH1, 64).  The KL26 processors have only 4 interrupt priority levels that are multiples of 64.  Lower numbers are higher priority.
  • Enable the interrupts with NVIC_ENABLE_IRQ(IRQ_SPI0)

I debugged the SPI interface using the protocol and logic analyzer tools in the Analog Discovery 2.  I found the user documentation for these tools really awful (almost no information), but I managed to get things working by trial and error (except for the “sensor” script options for the SPI protocol tool—that always resulted in the spinning beachball and force-quitting Waveforms 2015).  I initially tested with the “Master” tab of the protocol tool, but I fairly quickly switched to using the “Custom” tool which allowed me to set up more complicated sequences of reads and writes, though eventually I simplified back to writes that could be done with the “Master” tab.

The “debug” mode of the protocol tool sets up the logic analyzer to see the signals, but then doesn’t provide the decoding of the protocol in the protocol tool—one has to go to the logic analyzer to set up the triggering, switch to the protocol tool to send the stimulus, then switch back to the logic analyzer to see the results.  It is possible to get the protocol tool and the logic analyzer tool in different windows (double-click on the tab for the tool you want in a new window), but my screen is too small for showing both windows in sufficient resolution at once.

To see when the interrupt service routine for the SPI was active I added CORE_PIN1_PORTSET = CORE_PIN1_BITMASK to the beginning of the isr and CORE_PIN1_PORTCLEAR = CORE_PIN1_BITMASK, and used some wirewrap wire to get the pin 1 signal out to the logic analyzer. I’d not added test points for the unused pins, but because the Teensy board is socketed with female headers, it was easy to wrap a wire around the pin before pushing the board into the female headers, and use a loose header pin to connect the other end of the wire to DIO6 of the logic analyzer.

Here is a result of a test of sending the 4 commands in a row in an 11-byte frame, to make sure that the dummy bytes occur in the right places (in the first 2 and last slots of the 11-byte frame):

The MISO line shows the correct responses from the beacon detector: 0xff, 0xff, 1 (freeze ok), 0 (channel 0), 0x00e1=225=22.5°, power=0x08436020=138633248.

As it turns out, the end of the isr for the 4-byte response comes 0.4µs later than it should if there had not been any other bytes already in the queue. Indeed, if I start with the “4” command, things just barely work, because the isr routine starts a little sooner. The 6.8µs delay to the end of the isr routine suggests to me that the maximum safe rate for SCK is only about 1.15MHz, not 1.25MHz.  I’ll have to do a lot of testing with many data packets, to see what rate is really safe without intermittent errors.  That will have to wait until I’ve written a program to act as the master (unless I can figure out why the “sensor” script keeps crashing Waveforms 2015).

2017 August 6

Beacon detector board

I’m planning to sit in on CMPE 118/L (Mechatronics) this fall, and so I started looking over some of the material for the course from previous years.  One exercise involved designing a “beacon detector” that signals when it sees an infrared signal modulated with a 2kHz square wave. The exercise calls for an all-analog solution (phototransistor, transimpedance amplifier, active filter, rectifier, peak detector, …), which I plan to do when the time comes, but I got intrigued by the idea of doing an almost purely digital design.  That was the motivation for the Goertzel filter blog post.

I decided to take the digital design further and make a beacon detector that not only detects the 2kHz IR beacon, but also indicates what direction it is in.  To do this, I wanted 8 phototransistors around a circle, with one every 45°.  One can get a crude estimate of the angle from just which detector gets the strongest signal, but with wide-angle sensors one should be able to get finer estimates by looking at the ratio of the signals from two adjacent channels.

Because I was deliberately going for minimal analog design as an exercise, I used just a phototransistor and a pullup resistor for each channel, and a Teensy LC board for all the processing.  I chose SFH325FA side-look phototransistors, because they provide a nice, cubical package that I thought would make them easier to align.  They are surface-mount components, but with a 2.54mm pitch for the two terminals, they aren’t much harder to solder than through-hole parts.

For testing, I soldered one of the SFH325FA phototransistors to a pair of male header pins. This allowed me to experiment with different pullup resistor sizes in different lighting conditions and at different distances from an IR emitter.

My experimentation with different pullup resistors indicated that I could not operate in full sunlight, no matter what size pullup resistor I used—when the pullup was small enough that the phototransistor had sufficient voltage across it in full sunlight, the signal from the IR beacon was too small to be useful.  With AC-coupled amplifiers, I could have made it work, but I was committed to nearly pure digital solution.  If I had sunlight nearby, but the phototransistor itself was shaded, then I could go up to 22kΩ for the pullup without problems. The limiting factor was then that a very close beacon could saturate the detector, making it hard to determine power ratios.  I ended up choosing 22kΩ as my pullup, as I wanted to detect beacons from up to 2m away.

With a 22kΩ pullup and a strong signal, I can get a very clean “shark’s fin” waveform, because of the capacitance of the phototransistor acting with the resistor as a low-pass filter.  This low-pass filtering helps remove aliasing artifacts from the sampling by the analog-to-digital filter.

Behind each phototransistor I placed an LED, to indicate which channel had the maximum signal.  I charlieplexed the LEDs, so that I needed only 4 I/O pins for the 8 LEDs (I could encode up to 12 LEDs with 4 charlieplex wires). I used WP710A10SGC green LEDs for the indicators, because I had a lot of them around, but it would have been better to use an amber LED with a wide-angle, diffuse case, as the green indicators are only clearly visible over a fairly narrow angle.  The current-limiting resistors I used would keep the current low enough even with a low-forward-voltage red LED.

I also added an RGB LED to indicate the overall state—I used a common-anode one, because my son had a lot of them with diffuse cases, which are best for an indicator that needs to be seen from any angle.  The RGB LEDs were part of an unidentified lot from China, so I don’t have a part number or specs for them.  I hooked them up to PWM pins, so that I could adjust the brightness and color as needed.

I also designed in a connector for SPI connection, so that the board could be used a slave peripheral of another microcontroller.  I used Eagle on my old laptop to design the PCB (I know that in Need to find new PC board software and PCB CAD tools I said that I would be trying to switch to KiCAD or Diptrace, but I was lazy and stuck with what I already knew how to use).

I sent the design to Seeedstudio to make the PCB—like many of the Chinese firms that cater to hobbyists, they had a sale in July of boards up to 10cm×10cm for only $5.  Of course, it cost me another $21 for shipping with DHL, because I was too impatient to wait for Chinese air mail (and not trusting enough of the reliability). I chose Seeedstudio because they had the best user interface to their design-rule check, and at least as good pricing as anyone else.

The boards arrived quite quickly—only 8 days from order to delivery. Here is what they look like:

The back of the board has some documentation to remind me what is connected where.

The front of the board has relatively little documentation.

The boards are 8cm×8cm, fitting comfortably within both the cheap manufacturing limit and the Eagle free-version size limit.  I made them this big so that the Teensy LC board would fit without interfering with mounting holes (for M2 and M3 screws) and a central hole for attaching the board to a servo arm.

Getting a good right angle for the surface-mount phototransistors took some practice:

My first solder joint for the SFH325FA phototransistor tilted the transistor substantially, because the solder underneath formed a wedge. I reworked it a couple of times and finally got something sort of acceptable.

By the fifth phototransistor, I had worked out a technique that seemed to hold the phototransistor cleanly at a right angle. There is probably not much solder underneath the phototransistor, but the large wedge behind the phototransistor should provide sufficient mechanical strength.

Here are pictures of the populated board:

The back of the board does not look very different after being populated. I put one M3 screw in the bottom M3 screw hole, in order to see how compatible the screw hole design is with the screw head.

The top of the board, when populated shows how close channels 0 and 7 come to the Teensy board.

Here the board is on (powered through the USB cable), detecting an IR beacon about a meter away in the direction of channel 4. The green LED by the channel indicates the direction, and the green RGB LED indicates a strong signal.

I put the header pins on the pullup resistors, so that I could record the signal seen by the analog-to-digital converters.  Unfortunately, the signal is much noisier than I expected:

The large spikes are at 15kHz, and probably correspond to noise injected by the ADC sampling.

I turned off the beacon and looked just at the noise spikes, using the 10× probe on the oscilloscope to get better bandwidth.  I sampled at 100MHz and averaged 1000 traces to get a clean view of the signal (the triggering was set far enough from the background level that only fairly large spikes were captured, but close enough that the 1000 frames were gathered as quickly as possible).

The pulses are very short (2–3 µs), so almost certainly correspond to the charging of the sampling capacitor. After looking at this waveform, I changed my sample time on the ADC to 2µs (it had been 1µs) to reduce the noise in what the ADC reports.

This post has gotten more than long enough, though I still have a couple of things that should be added: a schematic diagram of the board and a plot of the reported angle vs actual angle.

The schematics from Eagle are really ugly, so I’ve been thinking about redrawing them with SchemeIt—perhaps that can be a subsequent post.

The reported angle vs. actual angle plot is going to require building a jig that allow me to set the angle precisely.  I tried jury-rigging something out of Lego today, but the result had too much slop—the board could not be reliably set level with the IR emitter at a fixed angle.  The OED-EL-1L2 5mm IR emitter does fit in the middle hole of a Lego Technic brick, so I using Lego to align the IR emitter was attractive. I may have to make something out of wood and MDF (medium-density fiberboard) for a more solid test jig.  The M3 screw holes will allow me to attach the board firmly to MDF with standoffs, and I can drill holes in Lego bricks to make a stand for the IR emitter.


Next Page »

Blog at

%d bloggers like this: