Uit Hack42
Project: LedBar | |
---|---|
Naam | LedBar |
Door | WitchDoc |
Status | Uitvoer |
Madskillz | Programming |
Doel / Omschrijving | |
Spacestate weergave op een LED lichtkrant | |
Alle Projecten - Project Toevoegen |
Het Idee
Een uit de vuilnis geredde lichtkrant gebruiken om de spacestate weer te geven.
Materiaal
Bovengenoemde lichtkrant, een serieele poort en Python
Status
Op basis van summiere documentatie heb ik een python script geschreven dat XML-achtige input kan parsen naar de lichtkrant.
Todo
- Beschikbare documentatie op de site plaatsen
- Programma verder uitwerken (effecten e.d.)
- Lichtkrant aansluiten op de ESpaceState
- Code in een vcs (git?)
- Code voorzien van commentaar
Code
#!/usr/bin/env python import sys import os import serial import argparse import string import xmlnode verbose = False BAUDRATE=2400 charLookup = { '"': 0x00, '\\': 0x04, '[': 0x0E, '_': 0x12, ']': 0x1E, ':': 0x20, '"': 0x22, '#': 0x23, '$': 0x24, '\'': 0x27, '(': 0x28, ')': 0x29, '*': 0x2A, ' ': 0x3A, '<': 0x5F, ';': 0x7B, } codeLookup = { 'start': [0xAA] * 9 + [0xBB], 'end': [0xBF, 0xB1], 'left': [0x80, 0x03], 'right': [0x81, 0x03], 'up': [0x82, 0x03], 'down': [0x83, 0x03], 'open-curtain': [0x84, 0x03], 'close-curtain': [0x85, 0x03], 'open-right': [0x86, 0x03], 'close-right': [0x87, 0x03], 'shift': [0x88, 0x03], 'sqz': [0x89, 0x03], 'flash': [0x8A, 0x03], 'jump': [0x8B, 0x03], 'doff': [0x8C, 0x03], 'dobig': [0x8D, 0x03], 'clear': [0x8E, 0x03], 'clock': [0x8F, 0x03], 'snow': [0x90, 0x03], 'dsnow': [0x91, 0x03], 'random': [0xA3, 0x03], 'speed': [0xA0], 'wait': [0xA1], 'gosub': [0xA2], 'prog': [0xAF] } specialCharLookup = { 'diamond': [0x01], 'home': [0x02], 'Aring': [0x03], 'uparrow': [0x05], 'pound': [0x06], 'curren': [0x07], 'ohm': [0x08], 'openleftarrow': [0x09], 'openrightarrow': [0x0A], 'car': [0x0B], 'note': [0x0C], 'circledot': [0x0D], 'Ouml': [0x0F], 'oslash': [0x10], 'clockchar': [0x11], 'aring': [0x13], 'sect': [0x14], 'unknown1': [0x15], 'aelig': [0x16], 'sigma': [0x17], 'glass': [0x18], 'soliduparrow': [0x19], 'square-1': [0x1A], 'solidcircle': [0x1B], 'boat': [0x1C], 'pacmanleft': [0x10, 0x1D], 'ouml': [0x1F], 'pacmanright': [0x10, 0x20], 'heart': [0x21], 'solidarrowright': [0x2C], 'solidarrowleft': [0x2D], 'solidaroowdown': [0x2E], 'arrowdown': [0x2F], 'AElig': [0x3E], 'Uuml': [0x5B], 'ucirc': [0x5C], 'aacute': [0x5D], 'Ecirc': [0xE0], 'Ntilde': [0x7C], 'ntilde': [0x7D], 'Auml': [0x7E], 'auml': [0x7F], 'amp': [0x26], 'space': [0x3A] } color = { 'black': 0x00, 'red': 0x01, 'green': 0x02, 'yellow': 0x03, 'rainbow': 0x20 } def debug(string): global verbose if verbose: print string class Tag(xmlnode.Node): def parse(self, retArray=[]): debug("parsing %s" % self.tag) self.colorCode = 3 self.big = 0x00 if self.tag.lower() in codeLookup: retArray += codeLookup[self.tag] if self.tag in ('speed', 'wait'): retArray += [int(self.value)] elif self.tag == 'gosub': retArray += [ord(self.value[0])] elif self.tag == 'prog': retArray += [ord(self.getAttribute('name'))] elif self.tag.lower() == 'text' or self.tag in specialCharLookup: if self.hasAttribute('background'): self.colorCode = color[self.getAttribute('background').lower()]*4 if self.hasAttribute('foreground'): self.colorCode += color[self.getAttribute('foreground').lower()] if self.hasAttribute('size') and self.getAttribute('size').lower() == 'big': self.big = 0x80 if self.tag.lower() == 'text': if self.value: for char in list(self.value): if char in charLookup: code = charLookup[char] else: code = ord(char) retArray += [self.colorCode, code + self.big] else: if len(specialCharLookup[self.tag]) > 1: retArray += specialCharLookup[self.tag] else: retArray += [self.colorCode] + specialCharLookup[self.tag] else: debug('Unknown tag: %s' % self.tag) for child in self.children: if child == self: continue child.colorCode = self.colorCode child.big = self.big retArray = child.parse(retArray) debug('retArray is %d chars' % len(retArray)) return retArray def size(self): retVal = len(self.value) for child in self.children: retVal += child.size() return retVal class LedBar(): def __init__(self, argv): global verbose self.serport = '/dev/ttyS0' self.file = None self._verbose = False parser = argparse.ArgumentParser(description = 'Lichtkrant interface') parser.add_argument('--version', action='version', version='%(prog)s 0.1') parser.add_argument('-v', '--verbose', action='store_true', dest='_verbose', help='Show verbose output') parser.add_argument('-p', '--port', action='store', metavar='SERIAL', dest='serport', help='Serial port') parser.add_argument('-f', '--file', type=argparse.FileType('r', 0), required=True, help='Input file, default is stdin') parser.parse_args(argv, namespace=self) if self._verbose: verbose = True debug('Verbose is on') self.serial = serial.Serial(self.serport, BAUDRATE) self._buffer = self.file.read() self.file.close() debug('File input: %s' % self._buffer) self.code = Tag.create(self._buffer) debug(self.code.xml()) self.write() def write(self): try: for char in self.code.parse(): debug('Writing %s' % hex(char)) self.serial.write('%c' % char) except serial.SerialException: debug('IO Error, no serial?') if __name__ == '__main__': LedBar(sys.argv[1:])
XML voorbeeld
Test code
<root> <start /> <prog name="A"> <open-curtain /> <space /> <text background="black" foreground="green" size='big'>#</text> <space /> <text background="black" foreground="green" size='big'>OPEN</text> <space /> <text background="black" foreground="green" size='big'>#</text> <wait>4</wait> <gosub>C</gosub> </prog> <prog name="B"> <snow /> <space /> <text background="black" foreground="green" size='big'>#</text> <space /> <text background="black" foreground="green" size='big'>OPEN</text> <space /> <text background="black" foreground="green" size='big'>#</text> <wait>2</wait> <gosub>C</gosub> </prog> <prog name="C"> <jump /> <pacmanleft/> <space /> <space /> <gosub>D</gosub> </prog> <prog name="D"> <clear /> <gosub>E</gosub> </prog> <prog name="E"> <jump /> <solidcircle /> <space /> <space /> <gosub>C</gosub> </prog> <prog name="F"> <space /> <space /> <space /> <space /> <space /> <space /> <space /> <space /> <space /> <wait>></wait> <gosub>A</gosub> </prog> <end /> </root>