fogbound.net




Mon, 16 Dec 2019

Maccabeam™ Part 6: Final Project Gallery

— SjG @ 9:38 pm

Previously:
Introduction
Part 1: Simulating candle-light with pseudo-random sequences
Part 2: Some physical structure
Part 3: When Exactly is Hanukkah?
Part 4: A Typical Programming Problem
Part 5: Oil and Lasers

So here we are, six days away from Hanukkah, and the first build of the Maccabeam™ is complete!

Below is video of it running, and a general build gallery. But before that, here are some thoughts and lessons that will go into Version 2 (and/or a kit, if that ever happens).

I build things the old-fashioned way. Everything’s soldered onto a breadboard with finicky little wires (I used wire-wrap wire, since it’s fine and easy to twist around). While this is fine for prototyping, it’s not great for a finished product. I need to learn to use a design app, and have printed circuit boards made.

A printed circuit board would make the positioning of the LEDs better, too. I bought the LEDs on a long strip, which I then cut and wired together. If I used surface-mount LEDs, I wouldn’t have to worry about the width of the strip and making each little segment fit in the channel. It sounds simple, but in the corner areas, it got congested.

The next design won’t just use a printed circuit board. It will also use standard connectors so the disparate parts may be added and removed easily while building.

Back to the LEDs. The decision to put the LEDs behind a layer of frosted acrylic to make the light more diffuse may not have been the right one either. When the “marching ants” animation is running to indicate the shamos lighting the other candles, the diffuse light bleeds over into the neighboring star-shaped windows, disrupting the flow of the animation a little.

The physical hanukkiah, all the laser-cut wood, works well, but it makes access to the internal components very difficult. The screws hold it together, but there’s enough play in the screw-holes that I supplemented with hot glue. When I had to replace one of the laser diodes that burned out, I had to tear the whole thing down. The next design should be more maintainable.

Speaking of lasers, the inexpensive laser diodes I purchased online are not really very good. The brightness varies dramatically! Now, they’re representing candles, so the variation is not a show-stopper, but the dimmer lasers are not bright enough for a well-lit room. You can see this in the video below.

I didn’t write about how I programmed the “music.” To make a long story short, I found sheet music of “Hanukkah Oh Hanukkah” online. Using the Wikipedia article on reading music, I translated the sheet music into the notes. The LCD display has a small piezo-electric speaker on it, and you can play notes by sending special codes on the serial lines to the display. So I took the notes, and translated them into those codes. It’s what the kids call chip-tunes, but perhaps next time I’ll go for the Teensy audio board, and play a stereophonic MP3 off of a memory card.

Another thing I didn’t write about was simulation mode. When the silver switch on the left is thrown to the left, the circuit gets time and date from the GPS unit. But I couldn’t wait for Hanukkah to test my code! Given the number of bugs found and fixed during development, it would have taken me several centuries worth of Hanukkahs to get it right. Therefore, I implemented a simulation mode. When the switch is to the right, we magically locate ourselves in Jerusalem, and set the time just before sundown on the 24th of Kislev. This allowed me to endlessly watch Hannukah arrive, and get the animated displays to my satisfaction.

Anyway, the results are below! We’ll see if it’s satisfactory in just a few days…

View of the LCD Display (Simulation mode)
Start of Day 6 (Simulation mode)

Mon, 9 Dec 2019

Maccabeam™ Part 4: A Typical Code Problem

— SjG @ 8:43 pm

Previously:
Introduction
Part 1: Simulating candle-light with pseudo-random sequences
Part 2: Some physical structure
Part 3: When Exactly is Hanukkah?

The build is coming together.

One discovery was a sneaky bug in the date conversion code. originally, the code had used standard C library for doing some time manipulations. These functions like mktime are used to convert from a structure containing year, month, day, hour, minute, and second to a single large number of seconds. Similarly, there’s gmtime which does the reverse. One nice thing about these functions is that you can use them for arithmetic, e.g., pass mktime all the regular values but a negative value for the hour, then convert back with gmtime to get the computed time. If you want to do the arithmetic yourself, you have to handle all of the boundaries (e.g., if you’ve rolled back into the past hour … or day … etc.)

Under the hood, mktime is doing something like what was described in the last posting about date conversions: it computes a number of seconds from the epoch given the year, month, day, hour etc. The epoch is an arbitrarily defined date and time standard. In most C / Unix environments, it’s the midnight of 1 January 1970 (e.g., the 0th second of 1970). The gmtime function does the reverse, converting a number of seconds from that epoch into a date and time.

I use this feature when computing sunrise and sunset times. Paul Schylter’s suntime.c returns a number of hours and/or minutes to each event. If the sun has already risen on the day you’re computing, for example, you’ll get a negative hour and or minute for sunrise. If the sunrise has not yet happened, the values are positive. I assembling times by adding those offsets to the current hour and minute, and passing the values to mktime. I didn’t have to worry whether the value was still the same hour or day, because mktime sorts it all out for me.

Somewhere along the line, however, I switched from the standard C library for time to using Paul Stoffregen’s Time Library. I did this because it integrates nicely with the GPS. What I neglected was that in C’s standard library, the components of the time structure are integers but in Paul’s library they are unsigned 8-bit integers.

For simple 8-bit integers, the highest-order bit is used for the sign of the number. In other words, a binary value of 00000011 would represent 3, and 10000011 would represent -3. That way, an 8-bit integer can represent values from -127 to 127. An unsigned 8-bit integer, however, uses the highest-order bit like any other bit, so 00000011 would still represent 3, but 10000011 would represent 131!

All this to say, my trick of passing possibly-negative hours or minutes into the equivalent of mktime was not doing what I had thought! When I thought I was computing the time of sunrise that was 7 hours earlier by passing hour - 7, I was actually computing the time as hour + 135. It turns out that tweaking Paul’s library to supports signed integers was simple.

The moral of this particular story is pay attention when changing C libraries.


Sun, 13 Oct 2019

Maccabeam™ Part 2: the physical structure

— SjG @ 5:30 pm

Background:
Introduction
Part 1: Simulating candle-light with pseudo-random sequences

I’ve been developing the software for the Maccabeam, and have a lot to write on that subject. But before I do that, I have a few words on the physical structure of the Maccabeam. There are some basic requirements: it needs to hold the microcontroller, the power regulation, the GPS unit, the lasers, the LCD status display, and some assorted lighting. It needs to be able to stand on its own, and, ideally, it should look nice.

The software is at the point where I need to figure out some hardware-dependencies. Specifically, I’ll need to lay out NeoPixels for part of the display.

What are NeoPixels? NeoPixels are a fancy form of light-emitting diodes (LEDs). LEDs are circuits that emit a narrow wavelength of light when the right voltage is applied, meaning that LEDs are emit a single color. Tricolor LEDs were a fancy development where three separate LEDs (one each of red, green, and blue) were combined in a single device, each with its own separate input lead, so you could change the color output. Other color LEDs took this a step further, combining this three-LED device with a pulse-width modulation driver that allows discrete levels for each color, thus allowing a whole range of apparent colors. NeoPixels are a product from AdaFruit industries that add an embedded circuit so that a whole string of RGB LEDs can be individually controlled with a single serial signal.

NeoPixels are available in a large number of form factors. For the Maccabeam, I have a thin tape with NeoPixels. It can be cut at various points, and then wires soldered between segments. The thing is, the software to drive the NeoPixels thinks of them as a single string, with each one having an address 1, 2, 3, … whatever. Since my layout is not linear like that, I have to think through the placement, and then figure out what the addresses are for each desired lighting operation. I’ll write more on this subject too.

I designed a basic plan. The design makes sense on the screen, but there could be a lot of issues when converting from digital to physical. So the next step was building a prototype, discovering the errors, and making corrections.

To digress a bit, I say I designed a basic plan. This is an oversimplification. I went through many designs over the past year or so, sometimes thinking from a visual sense, somethings thinking from a practical sense (e.g., where am I going to put wires?). I even built a prototype a year ago, with a design that I abandoned. Here’s a gallery of abandoned sketches and designs.

Design detail

Here’s a design detail. The brown rectangles up top are the vials, the red rectangles the lasers, and the strips with stars are the NeoPixels. The design has a front and back plane, with layers sandwiched between to give it the third dimension.

(I’ve been designing using Serif Lab’s Affinity Designer as my CAD program. I like it beacause it’s easy to use, allows precise sizing — you can even enter things like “1/2 + 1/16 – 1/32 in” into the sizing input, and it will give you the correct size! It’s a good tool, but I’m sure there are better tools for doing 3D design and CAD output. For example, if I design everything assuming 1/8″ thick materials, and then change my mind and decide to use 1/4″ thick materials, there’s no built-in intelligence to help me adjust all the interlocking tabs.)

Back to the final design. I chose Baltic birch plywood for the physical structure because it’s relatively easy to work with, and reasonably available from craft and hardware stores. Before designing, there’s the question of dimensions. CrashSpace’s laser cutter has a 24-inch by 12-inch bed, so that determines one set of dimensions. Then the question of how thick? I chose the nominally 1/8th inch (which is theoretically 3.2mm), and designed as if it was actually that size. It turns out that neither English nor Metric dimensions are exact.

One of the things that plagues laser-cutting with plywood is that the plywood thickness and/or density are not perfectly uniform. The same amount of laser power may cut perfectly in one portion of the wood, but not in another.

So I cut out a partial prototype, and measured and checked. It was a good thing, too, since I discovered a lot of oversights and errors. This is the iterative design process! Also, to address the laser-not-quite-cutting-through problem, next time I think I will either slow down the laser, or, alternatively, speed it up and run through the entire design twice.

Laser and vials in sockets

Sat, 20 Jul 2019

Maccabeam™ Part 1: Simulating candle-light with pseudo-random sequences

— SjG @ 3:05 pm

Background: Introduction

There are many components to the the Maccabeam™ Menorah project. In describing the build, I’ll address each component separately. This first posting will cover the simulation of candle-light.

The warm flicker of candlelight is a familiar sight, and unsurpringly there are a lot of examples and techniques you can find on the internet for simulating it. You could buy pre-made candle light LEDs from Evil Mad Scientist or JMFX, you could read Tim’s excellent analysis and implement something based upon it, or you could look up a myriad examples and how-tos at YouTube or Hackaday or elsewhere. Being perverse, I decided to implement my own approach.

My requirement is that my light source act as a binary source: either on or off. If I were to use LEDs, for example, I could actually change the current to change the brightness. But I’ll be using laser diodes which are either illuminated or not.

Since I’m using a Teensy microcontroller, I can use pulse width modulation (PWM) to control brightness. That’s a fancy way of saying turning the light on and off very rapidly, and simulating intensity. The higher the duty cycle (i.e., the larger percentage of the time the light is “on”), the brighter our eyes see illumination. This works on the property of the human eye known as “persistence of vision.” Our eyes and visual cortex integrate the incoming signal over time. It enables us to look at screens that rapidly flash changing images and see motion (i.e., movies) or a quickly moving point of illumination painting out a pattern and seeing an image (raster images, old tube-style TVs, etc).

So now the question is how to make the pattern of on and off that will look most like a candle flicker? Like many other people presented with this challenge, my first thought is to turn to a pseudo-random sequence generator. Specifically, my first thought is a linear shift-register sequence. Why? A couple of reasons, but the primary is that in the late sixties, my father worked at JPL and assisted Solomon Golomb, who wrote the definitive book on the subject. Thus, when I was in high school, my father helped me with an electronics project where we implemented one.

So, what’s this linear shift-register sequence? It starts with a shift register. This is a circuit with a series of cells or registers, each of which holds a bit with a value of either one or zero. Every time an external signal (like a clock pulse) comes, every value gets moved over to the neighboring cell. So a linear shift-register sequence adds circuity so that after each shift, it populates the input bit using some algorithmic function of its previous state. Depending on the function, it can create a long sequence that seems nearly random.

Consider the following 8-bit shift register:

8-bit linear shift register
8-bit linear shift register

At each tick of the clock, new value is computed by XOR-ing the values of bit numbers 3 and 7 (these are called the “taps”). The contents of each bit shifts to the position to its left, and the newly computed value populates bit number 0. In this case, the function is exclusive-or (XOR) which has the following truth table:

Input 1Input 2Output
000
011
101
110

So imagine only bit number 0 is set and the others are empty. The sequence will go as follows (a space is added between bits 3 and 4 to enhance readability):

0000 0001 (0 xor 0 -> 0, so we'll inject a 0) 
0000 0010 (0 xor 0 -> 0, so we'll inject a 0)
0000 0100 (0 xor 0 -> 0, so we'll inject a 0)
0000 1000 (0 xor 1 -> 1, so we'll inject a 1)
0001 0001 (0 xor 0 -> 0, so we'll inject a 0)
0010 0010 ...
0100 0100 
1000 1000 
0001 0000 
0010 0000 
0100 0000 
1000 0000 
0000 0001 

This particular configuration is considered “non-maximal” because even though 8 bits can represent 256 combinations, this sequence will repeat after every 12 clock cycles. If you move where the tap is, you can get better sequences. However, it turns out there is no maximal single-tap sequence for an 8-bit register. With an 8-bit register, you can get up to 217 step sequences if you put the tap at bit number 2 or 4. If you add more taps, you can achieve the full 255 states (the fully zero state is omitted, since it will always stay zero).

For our simulation, we want more than 255 steps anyway, so we go up to a 16-bit shift register and use taps that will yield a 65,535 step sequence. Several pages on the web (I like Burton Rosenberg’s page, as well as the Wikipedia reference) will help you find the right taps for any reasonable register you wish to create.

16-bit linear shift register
16-bit linear shift register

This is implemented in hardware with a handful of chips, or in software with a few lines of code like:

// code is unforgivably formatted, as good C should be[?]
uint16_t srs; // 16-bits for our shift register
srs = 1;
while (1)
{
   srs = (srs << 1) | (
        (
           (
              (
                 ((srs & 0x8000) == 0x8000) ^
                 ((srs & 0x2000) == 0x2000)
              )
              ^
              ((srs & 0x1000) == 0x1000)
            )
            ^
            ((srs & 0x0400) == 0x0400)
        )
);

So for the Maccabeam™, we’ll have a maximum of nine candles going at any one time. So if we have a stream of pseudo-random bits flying by in our 16-bit register, we could just pick nine arbitrary bits and route each one to our laser diode. The problem here is that the values keep shifting left, so there will be a visible pattern. So even if candle number 1 is driven by bit 5 and candle number 2 is driven by bit 8, candle 2 will always flicker three clock cycles after candle 1. Even if the order of the candles is different than the order of the bits, our brains are very good at detecting repeating patterns. It just won’t look very good.

So to break this visible pattern, we will drive each candle by OR-ing two bits together. The spacing between the two bits will be as close to unique as we can make it — of course, given that we only have 16 bits to play with, and nine candles, there will be some overlap.

Candle OR pattern

So you can see that there are two sets of candles that will always be illuminated simultaneous: candle 2 and candle 8; and candle 5 and candle S (the shamos/shamas/shamash. Here’s Wikipedia’s explanation of menorah candles).

There’s a question of timing, too. How frequently does the shift register shift? What looks good may or may not be what’s most like actual candle light. My first stab uses a 40ms cycle time. Adjustments may be in order.

I’m not at the point where I’m ready to hook up the lasers (still practicing the proper intonation of the cry “fire ze laaaaasers!“), but below is some sample video of this approach being run into lowly LEDs.

Blinky lights!

Sun, 14 Jul 2019

Sensor Problems

— SjG @ 9:28 am

I’m working on a circuit based on a 34685-MP chip bought at Marlin P Jones. The chip is supposed to be sensitive up to 7m away, but I’m not getting very reliable detection. My first thought was that, being next to a bunch of high-frequency stuff (a Teensy 3.2 with the audio shield), maybe it was interference.

The not-yet-functioning Annoy-o-Tron

I tried taking its output to the base of a transitor and lighting a LED to see if that was better. I got similar results.

I’m not sure what’s going on yet. If I do figure it out, I’ll post here.

Update: the Interwebs deliver! Following the recommendation I found in the comments on this article, I put the 34685-MP on a cable, and moved it away from the breadboard. Voilà! It now works as I had hoped!