Wheel of The Year
On 16 segment Display
The wheel of the year is divided in 8 intervals, and the corresponding segment is lit whenever the current day is inside the interval.
In the picture below, the segment will be lit from February 1st until March 20th
And while the weeks are passing the outer segments will start to lit sequentially, up the the point that the external wheel is complete. When the next date is reached all external segments will be turned off and the next internal segment will lit.
The intervals between festivals are not equally spaced, then every outer segment represents a different amount of days between the festivals.
The calculation of which segments to lit is performed by a table search where the index is the current day of the year, starting at February 1st . This table has the dimension of 8 x 9 because there are 8 festivals and 9 different states for the 8 external leds, from all lit to all unlit. Every entry is therefore a threshold day.
The search start at the last element and stops at the position where the present day is less than the element in table. The position at which the search ended is used as an entry to another 8x9 table of 16 bits that represents which segments shall be lit.
const PROGMEM uint16_t dayThreshold[72] = {
//Segment: all none 1seg 2seg 3seg 4seg 5seg 6seg 7seg (next)
/* Imbolc */ 0, 1, 6, 12, 18, 24, 30, 36, 42, /* 48 */
/* Ostara */ 48, 49, 53, 58, 63, 68, 73, 78, 83, /* 89 */
/* Beltane */ 89, 90, 95, 101, 108, 114, 120, 127, 133, /* 140 */
/* Litha */ 140, 141, 145, 150, 155, 160, 165, 170, 175, /* 181 */
/* Lammas */ 181, 182, 187, 193, 200, 206, 212, 219, 225, /* 232 */
/* Mabon */ 232, 233, 237, 242, 247, 252, 257, 262, 267, /* 273 */
/* Samhain */ 273, 274, 279, 285, 291, 298, 304, 310, 316, /* 323 */
/* Yule */ 323, 324, 328, 333, 338, 343, 348, 353, 358 /* 364 */
};
//
const PROGMEM uint16_t seasonPattern16segment[72] = {
_Imbolc_, _Imb_s0_, _Imb_s1_, _Imb_s2_, _Imb_s3_, _Imb_s4_, _Imb_s5_, _Imb_s6_, _Imb_s7_,
_Ostara_, _Ost_s0_, _Ost_s1_, _Ost_s2_, _Ost_s3_, _Ost_s4_, _Ost_s5_, _Ost_s6_, _Ost_s7_,
_Beltane, _Bel_s0_, _Bel_s1_, _Bel_s2_, _Bel_s3_, _Bel_s4_, _Bel_s5_, _Bel_s6_, _Bel_s7_,
_Litha__, _Lit_s0_, _Lit_s1_, _Lit_s2_, _Lit_s3_, _Lit_s4_, _Lit_s5_, _Lit_s6_, _Lit_s7_,
_Lammas_, _Lam_s0_, _Lam_s1_, _Lam_s2_, _Lam_s3_, _Lam_s4_, _Lam_s5_, _Lam_s6_, _Lam_s7_,
_Mabon__, _Mab_s0_, _Mab_s1_, _Mab_s2_, _Mab_s3_, _Mab_s4_, _Mab_s5_, _Mab_s6_, _Mab_s7_,
_Samhain, _Sam_s0_, _Sam_s1_, _Sam_s2_, _Sam_s3_, _Sam_s4_, _Sam_s5_, _Sam_s6_, _Sam_s7_,
_Yule___, _Yul_s0_, _Yul_s1_, _Yul_s2_, _Yul_s3_, _Yul_s4_, _Yul_s5_, _Yul_s6_, _Yul_s7_
};
//
// show season on 16 segment display
void showSeason16Seg ( uint16_t dayOfYear ) {
uint8_t th = 71; // count down to next threshold
while ( dayOfYear < pgm_read_word (dayThreshold + th ) ) {
th--;
}
// set correspondent pattern
displ16SegBuffer = pgm_read_word( seasonPattern16segment + th ) ;
}
On LED Ring
A second representation of the Wheel of the Year uses the LED ring to display the season, this time using colors. Again, a table search was used having the day of the year as the search term. The index is the position of the LED to be lit and is also used to get the color coordinates from another table.
const PROGMEM uint16_t dayThreshold24intervals [24] = {
12, 30, 48, 58 , 73, 89, 101, 120, 140, 150, 165, 181,
193, 212, 232, 242, 257, 273, 285, 304, 323, 333, 348, 364
};
//
const uint8_t PROGMEM seasonColors[24][3] = {
{ 0xFF, 0x00, 0x00 } , // RED
{ 0xE1, 0x00, 0x1E } , //
{ 0xC0, 0x00, 0x3F } , //
{ 0xA2, 0x00, 0x5D } , //
{ 0x81, 0x00, 0x7E } , //
{ 0x60, 0x00, 0x9F } , //
{ 0x42, 0x00, 0xBD } , //
{ 0x21, 0x00, 0xDE } , //
{ 0x00, 0x00, 0xFF } , // BLUE
{ 0x00, 0x1E, 0xE1 } , //
{ 0x00, 0x3F, 0xC0 } , //
{ 0x00, 0x60, 0x9F } , //
{ 0x00, 0x7E, 0x81 } , //
{ 0x00, 0x9F, 0x60 } , //
{ 0x00, 0xC0, 0x3F } , //
{ 0x00, 0xDE,...
Read more »