Making a Mayan Tzolkin Calendar
by oliverbogler in Circuits > Clocks
10452 Views, 43 Favorites, 0 Comments
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: 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!
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
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)
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
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.
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
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.
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
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.
Downloads
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;
}
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;
}