loading
Picture of Making a Mayan Tzolkin Calendar
OK, I will admit that I am a little obsessed with things Mayan at the moment, which explains why I wanted to make a Mayan Tzolkin calendar. I modeled the general layout and fabrication on the very nice Sleek Word Clock by scottbez1 which you can see here: http://www.instructables.com/id/Sleek-word-clock/?ALLSTEPS.

You can read about the Tzolkin Mayan calendar on Wikipedia http://en.wikipedia.org/wiki/Tzolk%27in. It is one of several calendars, and consists of 13 numbers and 20 day signs which appear in 260 combinations that rotate. In other words, with every change of the day the numer increases from 1 to 13 and then back to 1 again. Similarly the 20 day signs rotate. 

What I needed was a frame and face with the numbers and day signs on it, which I modeled on the Sleek World Clock, and relied on scottbez1's great instructions on printing the face and making the actual calendar. The electronics are Arduino and I put the code together from bits and pieces to take the date from an RTC, calculate the Julian Date and then work out where in the two Tzolkin rotation that day falls. LED's are controlled via a shift register. 

This is my first ever Arduino project - a testament to the great ease of use of this amazing technology! 
 
Remove these adsRemove these ads by Signing Up

Step 1: Assembling the Electronics on the breadboard for testing

Picture of Assembling the Electronics on the breadboard for testing
IMG_5964.jpg
IMG_5965.jpg
IMG_5966.jpg
1 Ikea RIBBA shadow box - $10

18 white, 5 red, 5 blue, 5 yellow LEDs (www.sparkfun.com SuperBright $0.50 each when bought in packs of 100) - $17
33 Resistors 330 Ohm 1/6th Watt - $2
1 Arduino Uno - R3 board www.sparkfun.com - $30
1 Real Time Clock Module DS1307 BOB-00099 www.sparkfun.com - $15
5 Shift Register 8-Bit - 74HC595 www.sparkfun.com - $7
1 Wall Adapter Power Supply - 9VDC 650mA www.sparkfun.com - $6

2 printed transparencies (see attached pdf on Step 2) - $1

Total cost: $88

Also: prototyping breadboards, prototyping leads, wire etc
Cardboard and other household items

Total cost: around $44 (using standalone ATMega168) or $67 (if you buy a full Arduino)

Step 2: Wiring it up

Picture of Wiring it up
IMG_5986.jpg
IMG_5987.jpg
After testing everything on the breadboard, I drew a wiring diagram on an enlarged photocopy of the board on which I would assemble the shift registers. You can see how I am collecting connections along the side for the different pins on the Arduino Uno. Also, the order of the shift registers is indicated. 

Then I put this part together, learning how to solder (not well, yet). The close up shows the different color coded wires. Brown and yellow wires going left are to the LED. Black is ground. Red is 5v. White and gray are latch and clock for the shift registers. Yellow exiting on the top and connecting shift registers on their right is data pin 2. 

Step 3: LED mounting

Picture of LED mounting
I made the LED board from black foam board, which was a mixed decision. The foam board is thick, holding the LED well, but not firmly, so that it was hard to control their angles. As a result, when everything is put together, some of the LED are at a slightly odd angle. Definitely an area for improvement.

Not shown, on the other side I made a series of walls around the LED to contain their light, made from cardboard and painted black. 

This part closely followed the Sleek Word Clock by scottbez1 which you can see here: http://www.instructables.com/id/Sleek-word-clock/?ALLSTEPS.

Step 4: The calendar mask

Picture of The calendar mask
I relied entirely on the instructions from scottbez1 here: http://www.instructables.com/id/Sleek-word-clock/step2/The-black-letter-mask/. I used my own mask made in Adobe Illustrator using purchased Tzolkin images from here: http://www.dreamstime.com/stock-images-maya-calendar-seals-tzolkin-vector-buttons-image14324534. You can see the pdf linked here. 

Step 5: Arduino code

Finally, the code which uses an RTC chip to set the time on the board, then calculates the Julian date and from that works out where in the two Tzolkin rotations the day falls. It then writes the appropriate bit sequence to the shift registers. This is my first Arduino program, and I relied heavily on the referenced sources and the Arduino cookbook to put it together. 

Code:

/*With thanks to the following sources for parts of this code and resources:

Playground Time Library: http://www.arduino.cc/playground/Code/Time

RTC chip: https://www.sparkfun.com/products/99

calculating days: http://arduino.cc/forum/index.php?topic=94925.0

Definition: The Julian date (JD) is a continuous count of days from 1 January 4713 BC.

*/





#include <Time.h> //include libraries needed for time calculation

#include <Wire.h>

#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t



int dataPin = 2; // define Pins for shift register

int clockPin = 3;

int latchPin = 4;



int seqtzn1[] = {128,64,32,16,8,4,2,1,0,0,0,0,0};//arrays controlling the LEDs

int seqtzn2[] = {0,0,0,0,0,0,0,0,128,64,32,16,8};

int seqtzds1[] = {128,64,32,16,8,4,2,1,0,0,0,0,0,0,0,0,0,0,0,0};

int seqtzds2[] = {0,0,0,0,0,0,0,0,128,64,32,16,8,4,2,1,0,0,0,0};

int seqtzds3[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,64,32,16};





void setup()

{

  Serial.begin(9600); // set up serial communication to computer

  pinMode(dataPin, OUTPUT); // set pin modes

  pinMode(latchPin, OUTPUT);

  pinMode (clockPin, OUTPUT);

    setSyncProvider(RTC.get);   // the function to get the time from the RTC

  if(timeStatus()!= timeSet)

     Serial.println("Unable to sync with the RTC");

  else

     Serial.println("RTC has set the system time");

}





void loop()

{

// calculate Julian Date and the two Tzolkin numbers using functions below

long jd = JulianDate();

int tzn = TzolkinNumber(jd);

int tzds = TzolkinDaysign(jd);

Serial.println(jd);

Serial.println(tzn);

Serial.println(tzds);

// send data to shift registers

digitalWrite (latchPin, LOW); // pull latch LOW start sending data

shiftOut(dataPin, clockPin, LSBFIRST, seqtzds3[tzds]);

shiftOut(dataPin, clockPin, LSBFIRST, seqtzds2[tzds]);

shiftOut(dataPin, clockPin, LSBFIRST, seqtzds1[tzds]);

shiftOut(dataPin, clockPin, LSBFIRST, seqtzn2[tzn]); //send the data

shiftOut(dataPin, clockPin, LSBFIRST, seqtzn1[tzn]);

digitalWrite(latchPin, HIGH); // pull latch HIGH stop sending data



delay(300000); // wait a while before repeating

}



// calculating Julian date jd

long JulianDate(){



  time_t t = now(); // store the current time in time variable t

  int todayDay = day(t);           // the day for the given time t

  int todayMonth = month(t);         // the month for the given time t

  int todayYear = year(t);          // the year for the given time t



  long centuries = todayYear/100;

  long leaps = centuries/4;                            

  long leapDays = 2 - centuries + leaps;         // note is negative!!

  long yearDays = 365.25 * (todayYear + 4716);     // days until 1 jan this year

  long monthDays = 30.6001* (todayMonth + 1);    // days until 1st month

  long result = leapDays + todayDay + monthDays + yearDays -1524.5;

  return result;

}





// calculating the two Tzolkin numbers that give position in Tzolkin rotation

int TzolkinNumber(long jd){

int result = (jd - 2456214) % 13; // the Tzolkin day number is calculated as being 0 to 12

return result;

}

int TzolkinDaysign(long jd){

int result = (jd - 2456203) % 20;  //calculate Tzolkin day sign 0 to 19 from 10.3.12 and number 0 wikipedia order

return result;

}
miguelp2 years ago
Just wanted to say that it is a very cool time clock you did and also love Mayan stuff
kelseymh2 years ago
Great looking project, and a really nice writeup, too! You've got a terrific level of detail here, which means other people could easily replicate it or even use it as a launching point for their own calendars/clocks.

In addition to the Tzolk'in (agricultural?) cycle, I guess that this could be expanded to include the Haab' (365-day solar year) cycle, and even a long-count (essentially, Julian number :-) index.

The Haab' would probably be most easily done with a separate, second construction, with an appropriate display panel.

The Long Count is much simpler computationally, using the Julian date with an offset for the Mayan epoch (something in 3114 BC, as I recall), and then just doing a series of modulo-20 and modulo-18 calculations. The display (with at least five digit positions) would probably have to be done differently, either with servos rotating the glyphs into position, or with maybe multi-pixel displays.
oliverbogler (author)  kelseymh2 years ago
Thanks for the kind comments. I agree - an expanded version would be fun to make. What I learned from this project is that the physical making of the object was the most challenging (for me). I had alot of wires and soldering and LED wrangling. There must be more elegant ways to work, and I will try it again with a better approach. That would be a good time to bring in the additional calendars.
I'm not so sure about "more elegant." What you described is pretty much how projects like this work :-) You might have been able to do the LED's more stably by making a custom circuit board with holes to position them, rather than soldering the LED and resistor leads directly.

In any event, this sounds like it was a lot of fun for you, and tied learning a new set of skills to something in which you were already interested. Congratulations!
kelseymh2 years ago
I do have a question. Where did you get your Julian date function? It doesn't look quite right to me. The algorithm I'm familiar with is equivalent to the one in Wikipedia, which doesn't look the same as yours.
oliverbogler (author)  kelseymh2 years ago
Hi kelseymh - I got the function from this thread:
http://arduino.cc/forum/index.php?topic=94925.0

You will see the exact code I used there, a little lower down.

I looked at the Wikipedia page, but the math was too challenging for me ;-(

For my purposes it may not be that critical to get the exact correct date, as the ultimate goal is to use Julian Date to calculate the Tzolkin state.

Oliver