Making a Mayan Tzolkin Calendar

by oliverbogler in Circuits > Clocks

10452 Views, 43 Favorites, 0 Comments

Making a Mayan Tzolkin Calendar

IMG_5993.jpg
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: https://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! 

Assembling the Electronics on the Breadboard for Testing

IMG_5963.jpg
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)

Wiring It Up

IMG_5989.jpg
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. 

LED Mounting

IMG_5988.jpg
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: https://www.instructables.com/id/Sleek-word-clock/?ALLSTEPS.

The Calendar Mask

Snapshot 10:28:12 9:32 PM.png
I relied entirely on the instructions from scottbez1 here: https://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. 

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;

}