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 »