import sys,time import parallel SLEEP_TIME = 0 NUM_CHARS = 8 MAX_LENGTH = 2048 MAX_SCROLL_LENGTH = MAX_LENGTH / NUM_CHARS - NUM_CHARS CHAR_END = 0 CHAR_BLANK = 0x80 ERR_TOO_LONG = 1 #constants for the individual segments A = 1 B = 2 C = 4 D = 8 E = 16 F = 32 G = 64 H = 256 J = 512 K = 1024 L = 2048 M = 4096 N = 8192 P = 16384 #array of seg patterns for all ascii characters charcodes = ( 0, #NUL 0, #SOH 0, #STX 0, #ETX 0, #EOT 0, #ENQ 0, #ACK 0, #BEL 0, #BS 0, #HT 0, #LF 0, #VT 0, #FF 0, #CR 0, #SO 0, #SI 0, #DLE 0, #DC1 0, #DC2 0, #DC3 0, #DC4 0, #NAK 0, #SYN 0, #ETB 0, #CAN 0, #EM 0, #SUB 0, #ESC 0, #FS 0, #GS 0, #RS 0, #US 0, #SPACE 0, #! B|F, #" A|B|C|D|E|F|G|H|J|M, ## A|F|H|G|C|D|J|M,#$ C|F|K|N, #% A|D|E|F|G|H|J|M,#& J, #' A|F|E|D, #( A|B|C|D, #) G|H|J|K|L|M|P, #* H|G|J|M, #+ N, #, H|G, #- 0, #. K|N, #/ A|B|C|D|E|F|K|N,#0 B|C, #1 A|B|G|H|E|D, #2 A|B|H|G|C|D, #3 F|G|H|B|C, #4 A|P|G|C|D, #5 A|F|E|D|C|G|H, #6 A|B|C, #7 A|B|C|D|E|F|G|H,#8 A|B|C|D|F|G|H, #9 0, #: 0, #; K|L, #< H|G|D, #= P|N, #> A|B|G|M, #? F|A|B|C|D|N|L, #@ E|F|A|B|G|H|C, #A A|B|C|D|J|M|G, #B A|F|E|D, #C A|B|C|D|J|M, #D A|F|E|D|H, #E (could also add segment G) A|F|E|H, #F A|F|E|D|C|G, #G F|E|B|C|G|H, #H A|D|J|M, #I B|C|D|E, #J F|H|E|K|L, #K F|E|D, #L E|F|P|K|B|C, #M E|F|P|L|B|C, #N A|B|C|D|E|F, #O A|B|G|H|F|E, #P A|B|C|D|E|F|L, #Q L|G|B|A|F|E|H, #R A|F|H|G|C|D, #S A|J|M, #T F|E|D|C|B, #U F|E|N|K, #V F|E|N|L|C|B, #W P|N|K|L, #X P|K|M, #Y A|K|N|D, #Z A|F|E|D, #[ P|L, #\ A|B|C|D, #] 0, #^ D, #_ P, #` A|B|C|D|N|G, #a F|E|D|C|G|H, #b G|H|E|D, #c B|C|D|E|G|H, #d D|E|F|A|K|H, #e F|E|H|A, #f F|A|B|G|H|C|D, #g F|E|G|H|C, #h M, #i B|C|D|E, #j F|H|E|K|N, #k J|M, #l E|H|M|G|C, #m E|H|G|C, #n E|H|G|C|D, #o E|F|A|B|G|H, #p B|C|A|G|H|F, #q E|H, #r A|F|H|G|C|D, #s F|E|D|H, #t E|D|C, #u L|C, #v E|D|M|C, #w P|K|N|L, #x F|H|G|B|C|D, #y A|K|N|D, #z A|P|H|N|D, #{ J|M, #| A|K|G|L|D, #} F|K|P, #~ 0 #DEL ) class Sign: def __init__(self, port = 0): """just initialize some things""" self.p = parallel.Parallel(port) def write(self, n): """write a byte to the sign""" time.sleep(SLEEP_TIME) self.p.setDataStrobe(0) time.sleep(SLEEP_TIME) self.p.setData(n) time.sleep(SLEEP_TIME) self.p.setDataStrobe(1) time.sleep(SLEEP_TIME) self.p.setInitOut(0) time.sleep(SLEEP_TIME) self.p.setInitOut(1) def advance(self): """advance() twiddles the Init line of the parallel port to increment the address that the next write() will write to.""" time.sleep(SLEEP_TIME) self.p.setInitOut(0); time.sleep(SLEEP_TIME) self.p.setInitOut(1); def reset(self): """reset() twiddles the Select In line to reset the address on the sign to zero. Reset before starting a write and after finishing.""" time.sleep(SLEEP_TIME) self.p.setSelect(0) time.sleep(SLEEP_TIME) self.p.setSelect(1) def open(self): """open() is somewhat wrongly named, but not terribly. it sets all the control lines high (off), then disables the external clocks and enables writes to the sign.""" self.p.setSelect(1) self.p.setInitOut(1) self.p.setDataStrobe(1) self.p.setAutoFeed(0) def close(self): """close() is the opposite of open(). It enables the internal clocks and starts the sign running normally.""" time.sleep(SLEEP_TIME) self.p.setAutoFeed(1) def writechar(self, c): """writechar() looks up a character (c) in the lookup table and writes the corresponding segment patterns two the sign.""" code = charcodes[ord(c)] self.write(code & 0xff | CHAR_BLANK) self.write((code & 0xff00) >> 8 | CHAR_BLANK) def writestr(self, str): """writestr() writes a string to the sign.""" if len(str) > MAX_LENGTH: print "Maximum length is %i characters; that was %i." % (MAX_LENGTH, len(str)) sys.exit(ERR_TOO_LONG) for char in str: self.writechar(char) if len(str) <= MAX_LENGTH - NUM_CHARS: if len(str) % NUM_CHARS: for i in range(0, NUM_CHARS - len(str) % NUM_CHARS): #print "**len(str) is %i, pad by 1**" % len(str) self.write(CHAR_BLANK) self.write(CHAR_BLANK) for i in range(0, 16): self.write(0) def scrollify(self, str): """scrollify() converts str to a string that can be written to the display that will appear to scroll.""" if len(str) <= NUM_CHARS: return str ret = '' str = ' ' * NUM_CHARS + str for i in range(0, len(str)): sub = str[i:i+NUM_CHARS] if len(sub) < NUM_CHARS: sub += " " * (NUM_CHARS - len(sub) % NUM_CHARS) ret += sub return ret def msg(self, str, scroll): """msg() is the only method you actually have to call. It enables writes, resets the sign, writes a string, resets again, and disables writes. Set scroll to true to make the message scroll.""" if (scroll): if len(str) > MAX_SCROLL_LENGTH: print "Maximum length is %i characters; that was %i." % (MAX_SCROLL_LENGTH, len(str)) sys.exit(ERR_TOO_LONG) str = self.scrollify(str) self.open() self.reset() self.writestr(str) self.reset() self.close() s = Sign() if len(sys.argv) > 1: s.msg(sys.argv[1], 1)