⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spokechar.py

📁 旋转16个LED灯控制程序
💻 PY
📖 第 1 页 / 共 3 页
字号:
                    
                    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 + -