📄 spokechar.py
字号:
for cBit in range(y1,y1+8):
# x1,cBit is the pixel address of the pixel we want. The bitmap
# is a linear array, 3 bytes per pixel, in row order...
pixel = ord(imagedata[((cBit*768)+x1)*3])
# shift the pixel into the byte
foo = foo << 1
if (pixel == 0):
foo |= 0x1
# print "* Bit x=",x1," y=",cBit
# else:
# print " Bit x=",x1," y=",cBit," pixel=",pixel
# move the new byte into the buffer, inverting it
# need to mask off the bits to ensure it's 8 bit
buff16[b] = (~foo) & 0xFF
# tell user what we're doing
self.SetStatusText('Checking address '+hex(x*4)+' of '+hex(768*4))
# read the 16 bytes. Since each column is 4 bytes, and x is the
# actual column number, the starting address in the eeprom is 4*x
check16 = spov.read_eeprom16(x*4)
#for b in range(0,16):
# print hex(x*4+b),'F=',buff16[b],'E=',check16[b]
# compare them against the blocks we computed
for b in range(0,16):
if buff16[b] != check16[b]:
self.SetStatusText('VERIFY ERROR: mismatch at '+hex(x*4+b)+' F=' + hex(buff16[b]) + ' E=' + hex(check16[b]) )
return
# move to the next block of 4 columns
x += 4
self.SetStatusText("Verified OK: %2.1f seconds" % (time.time() - lasttime))
except IOError:
self.SetStatusText("IO ERROR: died at address %s" % hex(x*4))
# load and write a charset to the EEPROM
def OnUploadButton(self, evt):
# the first step is to determine what charset must be loaded
dialog = wx.FileDialog(self,
"Choose an charset to load...", # title
"", "", # no defaults
"BMP files (*.bmp)|*.bmp", # BMP only
wx.OPEN); # open a file
# quit if they cancelled on us
if (dialog.ShowModal() == wx.ID_CANCEL):
return
# get the image from the file
charset = wx.Image(dialog.GetPath())
# ensure it's a charset (more or less, mostly less)
if (charset.GetWidth() != 768) or (charset.GetHeight() != 32):
self.SetStatusText("Cannot load - A SpokePOV character set is a 768 x 32 bitmap; the file you selected is %d x %d " % (charset.GetWidth(), charset.GetHeight()) )
return
# convert the image to monochrome (it ought to be that already)
# and get access to the bits
charset.ConvertToMono(0,0,0)
imagedata = charset.GetData()
# now we load the character set into the SpokePOV. This
# code is heavily cribbed from SpokePOV.py. Basically,
# we send the character set in blocks of 16 bytes. Each
# 32 pixel column in the character set is 4 bytes, so we
# send 4 columns at a time.
spov = SpokePOVComm()
try:
# x is the actual column number in the bitmap
x = 0
lasttime = time.time();
# while we still have columns to send
while x < 768:
# clear out our buffer of 16 bytes
buff16 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
# assume the bits are in simple order
# for each byte in the block
# print ""
# print "16 bytes starting at column ",x
# I must mention that the python "range" function
# defies all common sense. range(0,15) actually only
# executes values 0-14! Someone was on serious
# drugs...
for b in range(0,16):
# print ""
# print " Byte ",b
# what column is this byte actually in?
x1 = x + int(b/4)
# and what row do we start at?
y1 = 8*(b%4)
# assemble the byte
foo = 0
for cBit in range(y1,y1+8):
# x1,cBit is the pixel address of the pixel we want. The bitmap
# is a linear array, 3 bytes per pixel, in row order...
pixel = ord(imagedata[((cBit*768)+x1)*3])
# shift the pixel into the byte
foo = foo << 1
if (pixel == 0):
foo |= 0x1
# print "* Bit x=",x1," y=",cBit
# else:
# print " Bit x=",x1," y=",cBit," pixel=",pixel
# move the new byte into the buffer, inverting it
buff16[b] = ~foo
# tell user what we're doing
self.SetStatusText('Writing address '+hex(x*4)+' of '+hex(768*4))
# write the 16 bytes out. Since each column is 4 bytes, and x is the
# actual column number, the starting address in the eeprom is 4*x
spov.write_eeprom16(x*4, buff16)
# move to the next block of 4 columns
x += 4
self.SetStatusText("Charset Loaded: %2.1f seconds" % (time.time() - lasttime))
except IOError:
self.SetStatusText("IO ERROR: died at address %s" % hex(x*4))
# load and write a message to the EEPROM
def OnMessageButton(self, evt):
# wrap the editor text so we have valid lines to send
self.Wrap()
# get the text from the editor
theLines = self.ed.GetText()
# we store lines as blocks of 16 characters
# the last block is a terminator block, so
# our 1K means a max of 63 lines
if len(theLines) > 63:
self.SetStatusText("SpokePOV can hold 63 lines of text; you have %d." % len(theLines))
return
# pad all the lines to be 16 characters wide
newLines = []
# preset a line of blanks
blanks = ' '
# center each line in turn
for cLine in theLines:
# how many characters do we need to add?
n = 16-len(cLine)
# if that number is > 0, add the characters
if n > 0:
cLine = cLine + blanks[:n]
# add the revised line to the buffer we'll be uploading
newLines = newLines + [cLine]
# now we load the message into the SpokePOV.
#
# each line is sent as a single 16-byte block, but we
# subtract 32 from the character code before sending
# it to make life a little easier for the firmware
spov = SpokePOVComm()
try:
lasttime = time.time();
for x in range(0,len(newLines)):
# get the line to send
cLine = newLines[x]
# clear out our buffer of 16 bytes
buff16 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
# move each character into the buffer
for b in range(0,16):
buff16[b] = ( ord(cLine[b]) & 0x7F) - 32
# tell user what we're doing
self.SetStatusText('Writing address ' + hex(x*16) + ' of ' + hex(len(newLines)*16) + '[' + cLine + ']')
# write the 16 bytes out. We write them into the last 1K
# buffer, after the character set.
spov.write_eeprom16(3072+x*16, buff16)
self.SetStatusText("Writing Message Termination Block...")
# set the buffer to the FF termination values
buff16 = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
spov.write_eeprom16(3072+len(newLines)*16, buff16)
self.SetStatusText("Message Loaded: %2.1f seconds" % (time.time() - lasttime))
except IOError:
self.SetStatusText("IO ERROR: died at address %s" % hex(x*4))
# "That's all, folks!"
def OnTimeToClose(self, evt):
self.Close()
##############################################
# wrapper
##############################################
class SpokeSoft(wx.App):
def OnInit(self):
frame = SpokeSoftFrame(None, "SpokeChar - SpokePOV Character Set Utility")
self.SetTopWindow(frame)
frame.Show(True)
return True
# RJW 06/30/06
# use old start code, read in the preferences though
# at this time, we don't use them. Basically me being
# lazy and not wasting time deleting code, instead
# wasting time writing comments.
#
def main(argv=None):
global config, hubsize, num_leds
# read configuration
try:
config = ConfigParser.SafeConfigParser()
except:
# Assume the problem is a python version older than 2.3
# (which is when SafeConfigParser got added)
config = ConfigParser.ConfigParser()
config.read("SpokePOV.cfg")
try:
# 4 LEDs per inch
hubsize = float(config.get('preferences', 'hubsize')) * 4
except ConfigParser.NoOptionError:
hubsize = 4*1.5 # default is 2" diameter
try:
num_leds = int(config.get('preferences', 'num_leds'))
except ConfigParser.NoOptionError:
num_leds = 30
app = SpokeSoft(redirect=False)
if argv is None:
argv = sys.argv
app.MainLoop()
if __name__ == '__main__':
# Redirect stdout/stderr
# sys.stderr = open("stderr.log", "w")
# sys.stdout = open("stdout.log", "w")
sys.exit(main())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -