""" Raspberry Pi Nixie Clock Prototype Scott M Baker, 2013 http://www.smbaker.com/ Modified to account for Arizona Mountain Standard Time and adjust for 12 hour time and to include two neon indicators for AM and PM. We do not observe DST so this simplifies the code! """ import RPi.GPIO as GPIO import time import datetime import sys import os PIN_DATA = 23 PIN_LATCH = 24 PIN_CLK = 25 PIN_AM = 27 PIN_PM = 22 class Nixie: def __init__(self, pin_data, pin_latch, pin_clk, digits): self.pin_data = pin_data self.pin_latch = pin_latch self.pin_clk = pin_clk self.digits = digits #set up GPIO using BCM numbering GPIO.setmode(GPIO.BCM) # Setup the GPIO pins as outputs GPIO.setup(self.pin_data, GPIO.OUT) GPIO.setup(self.pin_latch, GPIO.OUT) GPIO.setup(self.pin_clk, GPIO.OUT) GPIO.setup(PIN_AM, GPIO.OUT) GPIO.setup(PIN_PM, GPIO.OUT) # Set the initial state of our GPIO pins to 0 GPIO.output(self.pin_data, False) GPIO.output(self.pin_latch, False) GPIO.output(self.pin_clk, False) GPIO.output(PIN_AM, False) GPIO.output(PIN_PM, False) def delay(self): # We'll use a 10ms delay for our clock time.sleep(0.010) def transfer_latch(self): # Trigger the latch pin from 0->1. This causes the value that we've # been shifting into the register to be copied to the output. GPIO.output(self.pin_latch, True) self.delay() GPIO.output(self.pin_latch, False) self.delay() def tick_clock(self): # Tick the clock pin. This will cause the register to shift its # internal value left one position and the copy the state of the DATA # pin into the lowest bit. GPIO.output(self.pin_clk, True) self.delay() GPIO.output(self.pin_clk, False) self.delay() def shift_bit(self, value): # Shift one bit into the register. GPIO.output(self.pin_data, value) self.tick_clock() def shift_digit(self, value): # Shift a 4-bit BCD-encoded value into the register, MSB-first. self.shift_bit(value&0x08) value = value << 1 self.shift_bit(value&0x08) value = value << 1 self.shift_bit(value&0x08) value = value << 1 self.shift_bit(value&0x08) def set_value(self, value): # Shift a decimal value into the register str = "%0*d" % (self.digits, value) for digit in str: self.shift_digit(int(digit)) value = value * 10 self.transfer_latch() def main(): try: nixie = Nixie(PIN_DATA, PIN_LATCH, PIN_CLK, 6) # Uncomment for a simple test pattern # nixie.set_value(123456) # Repeatedly get the current time of day and display it on the tubes. # The time retrieved will be local time in 24 hour format if you ran # sudo dpkg-reconfigure tzdata and set for your local timezone. # By default, the Raspberry Pi uses UTC. while True: dt = datetime.datetime.now() # print ("%d " % dt.hour + "%d " % dt.minute + "%d " % dt.second) # uncomment for testing new_hour = dt.hour # Create variable to allow adjustments for 12 hour mode # print(new_hour) # Notice that nixie hour is multiplied by 10,000 and nixie minute by 100. # I am using 6 digits instead of 4 to show hours, minutes, and seconds. # This results in either a single 5-digit number or a single 6-digit number. # Single digit hours may appear in tubes like: 1 00 00 # Double digit hours should appear in tubes like: 12 00 00 if(new_hour > 12): #convert 24-hour time to 12-hour time new_hour = new_hour - 12 nixie.set_value(new_hour*10000 + dt.minute*100 + dt.second) #print(new_hour*10000 + dt.minute*100 + dt.second) # uncomment for testing GPIO.output(PIN_PM, True) # PM indicator = on GPIO.output(PIN_AM, False) # AM indicator = off if(dt.hour >= 1) and (dt.hour <= 12): new_hour = dt.hour nixie.set_value(new_hour*10000 + dt.minute*100 + dt.second) #print(new_hour*10000 + dt.minute*100 + dt.second) # uncomment for testing GPIO.output(PIN_PM, False) # PM indicator = off GPIO.output(PIN_AM, True) # AM indicator = on if(dt.hour == 0): new_hour = dt.hour + 12 nixie.set_value(new_hour*10000 + dt.minute*100 + dt.second) #print(new_hour*10000 + dt.minute*100 + dt.second) # uncomment for testing GPIO.output(PIN_PM, False) # PM indicator = off GPIO.output(PIN_AM, True) # AM indicator = on except: sys.stderr.write("\x1b[2J\x1b[H") # Clears screen print("If you see this, program has terminated!") # End Timezone Adjustment finally: # Cleanup GPIO on exit. Otherwise, you'll get a warning next time to # configure the pins. GPIO.cleanup() if __name__ == "__main__": main()