Monthly Archives: June 2015

Calculating days of the week on a Propeller

I’m doing a project using a Parallax Propeller microcontroller at the moment. It’s like a normal microcontroller, but psychedelic. Eight cores, peripherals defined almost entirely in software, and primarily programmed in a cunning language called Spin. Spin is a very efficient interpreted language and makes it possible to squeeze a lot into the Propeller’s meagre 32K of RAM.

The project has a real-time clock maintained by an off-the-shelf clock chip, but this application needs to know the day of the week as well. Of course, I can get the user to set the day of the week when they set the clock, but it’s unintuitive to have to set it manually, and this thing is supposed to be easy to use.

IMG_0006

I looked in to algorithms for calculating the day of the week given a year, month and date. There are loads of them. The Wikipedia page has lots, and this Stackoverflow page has a load of useful suggestions. There was one particularly simple one which appeared in both places, credited to Tomohiko Sakamoto on the comp.lang.c Usenet newsgroup in 1993. I don’t care about the theory behind the algorithm, I just want it to work and to be simple to program in Spin. The original is in C and looks like this:

dayofweek(y, m, d)	/* 1 <= m <= 12,  y > 1752 (in the U.K.) */
    {
        static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
        y -= m < 3;
        return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
    }

My Spin version looks like this:

DAT
 dayTable BYTE 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4

PRI decFromBCD(n)
 return (n&$f)+10*((n&$f0)>>4)

PRI calcDayFromDate | y
 y := decFromBCD(year) + 2000
 if month < 3
   y--

 day := (y + (y/4) - (y/100) + (y/400)
       + dayTable[decFromBCD(month)-1]
       + decFromBCD(date)) // 7

Mine looks more complex, and the one reason for that is that the clock chip maintains its counts in BCD (binary-coded decimal) rather than straight decimal. There might be a cunning way to modify the algorithm to take BCD values directly, but I took the easy route of implementing a function which converts an 8-bit BCD value into decimal.

The code assumes the presence of three variables: year (0 to 99, starting at the year 2000), month (1 to 12) and date (1 to 31) and sets a variable day in the range 0 to 6, where 0 is Sunday.

When implementing the clock in your project, don’t forget to compensate for the leap second tonight.

Advertisements

Solidlights new LED upgrade

The first Solidlights products to be sold used the Lumileds Luxeon III LEDs, which were state of the art back in 2003. Technology has moved on since then, however, and modern LEDs are much more efficient – they produce a lot more light for the same amount of electricity. Though I’m no longer actively developing Solidlights, I occasionally tinker with upgrades to the ones I use regularly.

For a year or so now I’ve been using a modified Solidlights 1203D dynamo light fitted with Cree XP-G2 LEDs. Getting the best from them requires modifications to the lenses, too, but it’s worth it: the theoretical maximum light output from each LED is 488 lumens, whereas the old Luxeon III could only manage about 80 lumens. I’ve done the modification informally for a couple of customers, too, and they’ve been happy with it.

xpg2

There’s been more interest recently, so I’ve made this upgrade available in the Solidlights on-line shop. It’s listed as part number 99002 under ‘service and repairs’.