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>
