fogbound.net




Sat, 26 Oct 2019

Maccabeam™ Part 3: When Exactly is Hanukkah?

— SjG @ 4:37 pm

Background:
Introduction
Part 1: Simulating candle-light with pseudo-random sequences
Part 2: Some physical structure

I want the Maccabeam to automatically determine when to illuminate the lasers (“candles”). Specifically, they should light at the beginning of each night of Hanukkah, and burn for about an hour. So how will it know when the time comes?

One of the hardware components f the Maccabeam is a GPS receiver. The specific model I got is this now discontinued model, but there are many equivalents. They’re miraculous little circuits: they have an antenna with which they receive signals from a constellation of sophisticated satellites, and they spit out a stream of information. This specific model has a 9600 baud serial output that provides timestamp and coordinate information, along with a highly-precise pulse-per-second (PPS) signal. To oversimplify, my software running on the Teensy gets very accurate time, date, and location information.

So, I know what time and date it is. Problem solved, right? Not exactly. Hanukkah is a holiday that falls on the same day every year — on the Hebrew calendar that is: the 25th of Kislev. The GPS yields data on what’s the usual, every-day calendar in the US, also known as the Gregorian calendar. I can find December in the Gregorian calendar, but not Kislev! Still, given that both calendars are used to measure time, it should be pretty easy to convert between them, right? Once again, not exactly.

The Gregorian Calendar is a Solar calendar, meaning that the year is tied to the position of the earth relative to the sun; one revolution around the sun is one year. The solar year is divided into months by set numbers of days, so a given month will find Earth in the same orbital position every year. The Hebrew calendar, however, is a Lunar-Solar calendar. That means the year is based on the months, and months are tied to the phase of the moon. What makes a Lunar-Solar calendar complicated is that the Solar year is not evenly divisible by the moon phases. A lunation or lunar phase (meaning from full moon to full moon, or new moon to new moon) is roughly 29.5 days, while the solar year is close to 365.24 days. That gives us 12.38 lunar cycles per year. You can see how the Gregorian calendar adding an extra day every four years (with a few exceptions) keeps the year in sync with the seasons. The Hebrew calendar uses a similar approach, except it’s a leap month! This month gets added on a complicated schedule, which works out to roughly seven times every nineteen years. This ensures a given month will fall in a given season. Interestingly, not all calendars are concerned with having months correlated with specific seasons. For example, the Islamic calendar is purely lunar, which is why Islamic holidays are not tied to seasons and they drift relative to the Gregorian calendar.

In any case, for the Maccabeam to work, I need an algorithm to convert from the Gregorian calendar to the Hebrew calendar. The usual approach is to find a specific moment in time, figure out the date in both calendar systems, figure out how many days have passed since that specified moment, and then calculate months and days from that number. I relied upon the authoritative technical book on the subject, Calendrical Calculations by Nachum Dershowitz and Edward Reingold. They discuss this conversion problem in enormous detail, and provide LISP code [!] to convert between many different kinds of calendars (Gregorian, Julian, Coptic and Ethiopic, Islamic, Hebrew, Ecclesiastical, Old Hindu, Mayan, Balinese Pawukon, Persian, Baha’i, French Revolutionary, Chinese, modern Hindu, and Tibetan). They also provide some thought-provoking discussion of units of timekeeping (what does a “day” mean for a someone living above the Arctic Circle, for example, or why would someone who lived on the Equator care about solstices, or even what’s the purpose of units like the week?)

To make a long story short, I used their algorithms to implement a C version of the conversions between Hebrew and Gregorian calendars. So now I’m set, right? Well, still not quite. There are still a few problems.

First, we have to go back to the realization that measuring time is complicated, and even simple concepts like “days” are not simple. In the Gregorian calendar, the start of the day is at a point in time we call midnight, 12:00 AM. Historically, this was set a the halfway point between sunset and sunrise (or twelve hours from the Sun’s highest position in the sky), but now it’s more abstract. We have time zones loosely based on a geographic offset from Greenwich England. Seems … uh … simple. The Hebrew calendar, however, doesn’t use midnight as the point when the date changes — instead, the day begins at sundown. So even if I know the exact date on the Gregorian calendar, it’s one of two days in the Hebrew calendar depending on whether the sun has set or not.

Oh, and one other problem. The GPS gives me time and date, but not the time and date for my specific location. No, it’s giving me time in Coordinated Universal Time (UTC), which is the time at 0º longitude1. To go from UTC to local time, you need to know your time zone. For example, if it’s midnight at UTC, it’s still the previous date in Los Angeles, but you can’t know that unless you have a map that tells you how many hours Los Angeles is offset from UTC. Similarly, if you’re east of the 0º longitude, for certain hours you will be a day ahead of UTC.

Time zones are quite a thing. If you want to know whether a programmer has ever had to deal with them, just say something like “my code works prefectly except in Nepal” and see if they start shedding tears and muttering about UTC + 5.75. Meanwhile, I’m in Los Angeles. Time for me is either 7 or 8 hours behind2 UTC depending on whether it’s Daylight Saving Time or Standard Time. Oh yes, another complication! When you mix Daylight Savings Time into the equation, you discover you need to know your political boundary down to the county level to know whether to shift an hour or not!

There are code libraries where you enter your latitude and longitude, and they will tell you the time zone and whether or not DST is in effect. These libraries get updated frequently, and they are not small. They will not fit in the memory of my Teensy. But all is not lost! Remember that the Hebrew day starts at sundown? So we don’t have to know the local clock time, we need to know the local sunset time. Given your coordinates and the time at UTC, you can compute sunrise and sunset times. Before we get too confident and start thinking this is perfectly straightforward, let’s note that there are multiple definitions of sunset. Technically, it’s defined as when the upper edge of the sun disk is behind the curve of the earth, but atmospheric refraction makes the sun visible even when it’s past that mark. When you see the sun set, it can actually be several degrees beyond that point. That’s why there are different definitions of civic, nautical, and astronomical twilight. Still, for simplicity’s sake, we’ll use geometric sunset.

Given the date and time at UTC and the sunrise/sunset time locally, you can figure out if it’s the same Hebrew day without needing to know anything about time zones or daylight savings time. With code that gives the sunrise and sunset times in UTC for your location, you can calculate sunrise and sunset times for for the current date, the previous date, and the next date. Then you can figure out which of those events have passed, and which are yet to occur. If it’s before sunset of the previous UTC date, you subtract one. If it’s after the sunset of the current UTC date, you add one.

In any case, I used Paul Schylter’s sunriseset.c library to compute the geometric sunset, and then figure out if I need to add or subtract from the date after converting. So now I can compute the correct Hebrew date, and I can also compute the number of hours and minutes to sundown. So if it’s the 24th of Kislev, I can count down the hours and minutes until the date clicks over to the 25th, and Hanukkah begins. Hooray! We now know when it’s Hannukah!

1 Strictly speaking, UTC is not exactly the time at 0º, but is kept within a second or so of it. For my purposes, I consider it the same.

2 This is often confusing, because UTC is 7 or 8 hours ahead of Los Angeles time, but the notation is UTC-7 or UTC-8, which might make you think Los Angeles is ahead. But it’s clearer when you look at the math, e.g., when it’s say 18:00 UTC, it’s 10:00 PST.


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

Mon, 16 Sep 2019

Ambitopian

— SjG @ 10:42 pm

OK, it’s a kind of awkward word. It combines a Greek root and a Latin root, which is probably not a terrible thing since there are plenty of other good words that do that. I like it more than the more consistent “amphotopian” which sounds like something optical, or “ambilocian” which sounds like some rich-person drug.

Utopian and dystopian are also awkward, when you think about it. Utopia was Thomas More’s “No Place” — it was too ideal to exist. The word gradually drifted from his idyllic perfect island in the Atlantic to become the generic perfect place. You’d think the opposite of No Place would be Some Place, but of course that misses the flavor somewhat. Thus the opposite “dystopia” came about. According to Etymonline.com, the word was first used in this sense as early as 1868 (but had an earlier medical definition of an out-of-place organ).

So what of a speculative place neither exemplary nor exactly infernal? A place where both good and bad happens? A place where people muddle through as best they can? A place like everywhere, really?

I’m going to go with “ambitopian.” Both places. Neither heaven nor hell, where people are imperfect, some base, some noble, all going about their business. A place with a balance, over time, where the pendulum swings but always returns to somewhere near a center. With any luck, there’s progress, but if there is, it’s probably gradual.

Filed in:

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!