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

📄 spokechar.py

📁 旋转16个LED灯控制程序
💻 PY
📖 第 1 页 / 共 3 页
字号:
#!/usr/bin/env python

# The software for SpokePOV is available for use in accordance with the 
# following open source license (MIT License). For more information about
# OS licensing, please visit -> http://www.opensource.org/
#
# For more information about SpokePOV, please visit
# -> http://www.ladyada.net/make/spokepov
#
#                                     *****
# Copyright (c) 2005 Limor Fried
#
# Permission is hereby granted, free of charge, to any person obtaining a 
# copy of this software and associated documentation files (the "Software"), 
# to deal in the Software without restriction, including without limitation 
# the rights to use, copy, modify, merge, publish, distribute, sublicense, 
# and/or sell copies of the Software, and to permit persons to whom the 
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in 
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#                                     *****

# SpokeChar.py was cribbed from SpokePOV.py by Robert Woodhead, trebor@animeigo.com,
# changes (c) 2006 Robert Woodhead, released under the above license.

import sys, time
import parallel
import array
import wx
import math
import ConfigParser
import pickle

import  wx.lib.editor    as  editor

# Note: this is my first Python/wx program. It probably has mistakes, bugs,
# bad code. Oh well.  -- ladyada

# RJW 06/30/06 - pretty much my first Python program too.  This nesting
# determined by the indentation stuff is a total brainfart, IMHO.
#
# I have deleted stuff that isn't really needed but some stuff is still
# leftover from SpokePOV.py

#default rotation
autorotation = 0

#default hub diameter is 2" (*4 LEDs per inch)
hubsize = 2*4

#default LEDs per row is 30, BMX wheels have 22
num_leds = 30

############## spoke interface commands, must be the same in firmware!

COMP_CMD_SETFLED = 0x81
COMP_CMD_SETBLED = 0x82
COMP_CMD_CLRFLED = 0x83
COMP_CMD_CLRBLED = 0x84
COMP_CMD_RDEEPROM = 0x85
COMP_CMD_WREEPROM = 0x86
COMP_CMD_RDEEPROM16 = 0x87
COMP_CMD_WREEPROM16 = 0x88
COMP_SUCCESS = 0x80

############## spokepov parallel port pins

SPI_CLK = 3;    # DATA3
SPI_DO = 0;     # DATA0

############## variables stored in the microcontroller

EEPROM_ROTOFFSET = 0x8000
EEPROM_MIRROR = 0x8001

####################################################
# this class talks to the actual spokes
####################################################

class SpokePOVComm:
    def __init__(self):
        self.p = parallel.Parallel()  # open LPT1
        self.out(0xFF)

    # if there's a spokepov on the other side, this pin should be low
    
    def connected(self):
        r = ~ self.p.getInAcknowledge()
        return r

    # since theres only a byte-wide byte output function, these functions
    # allow setting and clearing individual pins

    def out(self, b):
        self.data = b
        self.p.setData(self.data)

    def setbit(self, b):
        self.data |= 1 << b
        self.p.setData(self.data)

    def clrbit(self, b):
        self.data &= ~(1 << b)
        self.p.setData(self.data)

    # bit-bang the SPI protocol over to the microcontroller

    def spi_xfer(self, c):
        #print "sending %02x\n" % c
        x = 7
        ret = 0
        
        while x >= 0:
            
            if (self.connected() == 0):
                raise IOError, "not connected"

            # send data out
            if c & (1 << x):
                self.setbit(SPI_DO)
            else:
                self.clrbit(SPI_DO)
            self.setbit(SPI_CLK)

            #print "^"
            #ya = raw_input()

            time.sleep(0.001)

            # get data in
            ret <<= 1
            ret |= self.p.getInBusy()
            
            self.clrbit(SPI_CLK)
            time.sleep(0.001)

            #print "v"
            #ya = raw_input()

            
            x -= 1

        #print "got %02x" % ret
        return ret

    # read one byte from the external EEPROM

    def read_eeprom(self, addr):
        self.spi_xfer(COMP_CMD_RDEEPROM)
        #time.sleep(0.01)
        self.spi_xfer((addr >> 8) & 0xFF)
        #time.sleep(0.01)
        self.spi_xfer(addr & 0xFF)
        #time.sleep(0.01)
        val = self.spi_xfer(0)
        #time.sleep(0.01)
        ret = self.spi_xfer(0);
        if (ret != 0x80):
            print "failed! 0x%02x" % ret
            raise IOError, "Didn't succeed"        
        return val

    # read 16 bytes from the external EEPROM (faster!)

    def read_eeprom16(self, addr):
        self.spi_xfer(COMP_CMD_RDEEPROM16)
        self.spi_xfer((addr >> 8) & 0xFF)
        self.spi_xfer(addr & 0xFF)
        x = 16
        val = []
        while (x != 0):
            val.append(self.spi_xfer(0))
            x -= 1
            
        ret = self.spi_xfer(0);
        if (ret != 0x80):
            raise IOError, "Didn't succeed"        
        return val

    # write a byte to the external EEPROM
    
    def write_eeprom(self, addr, val):
        self.spi_xfer(COMP_CMD_WREEPROM)
        self.spi_xfer((addr >> 8) & 0xFF)
        self.spi_xfer(addr & 0xFF)
        self.spi_xfer(val)
        ret = self.spi_xfer(0);
        if (ret != 0x80):
            raise IOError, "Didn't succeed"        

    # write 16 bytes to the external EEPROM
    
    def write_eeprom16(self, addr, val):
        self.spi_xfer(COMP_CMD_WREEPROM16)
        self.spi_xfer((addr >> 8) & 0xFF)
        self.spi_xfer(addr & 0xFF)
        x = 0
        while (x != 16):
            self.spi_xfer(val[x])  
            x += 1
            
        ret = self.spi_xfer(0);
        if (ret != 0x80):
            raise IOError, "Didn't succeed"        
    
    # send a command to the SpokePOV
    
    def sendcmd(self, cmd, arg):
        self.spi_xfer(cmd)
        time.sleep(0.005)
        self.spi_xfer(arg)
        time.sleep(0.005)
        ret = self.spi_xfer(0);
        if (ret != 0x80):
            raise IOError, "Didn't succeed"


#---------------------------------------------------------------------------

###################################
# The top-level frame (menus and buttons)
###################################

class SpokeSoftFrame(wx.Frame):

    filename = None
    ed = None
    filemenu = None
    tweakmenu = None
    
    def __init__(self, parent, title):
        global autorotation
        
        # RJW make some arbitrary size
        
        wx.Frame.__init__(self, parent, -1, title,
                          pos=(50, 50), size=(500,630),
                          style=(wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.RESIZE_BOX | wx.MAXIMIZE_BOX)))

        # not quite sure why we do this, but...
        
        self.SetTitle("SpokeChar - SpokePOV Character Set Utility - (Untitled)")
        
        # Create the menubar
        
        menuBar = wx.MenuBar()

        # the file menu 
        
        self.filemenu = wx.Menu()

        # create menu items
        
        self.filemenu.Append(0, "Open...", "Open a caption .txt file")
        self.filemenu.Append(1, "Save", "Save captions")
        self.filemenu.Append(2, "Save As...", "Save into a different file")
        self.filemenu.AppendSeparator()
        self.filemenu.Append(3, "Upload Charset", "Transfer charset BMP to SpokePOV")
        self.filemenu.Append(4, "Verify Charset", "Check charset BMP vs SpokePOV EEPROM")
        self.filemenu.AppendSeparator()
        self.filemenu.Append(5, "Upload Message", "Upload Message to SpokePOV")
        self.filemenu.AppendSeparator()
        self.filemenu.Append(wx.ID_EXIT, "E&xit", "Exit")

        self.filemenu.Enable(1,False)
        
        # bind to their actions
        
        self.Bind(wx.EVT_MENU, self.OnOpen, id=0)
        self.Bind(wx.EVT_MENU, self.OnSave, id=1)
        self.Bind(wx.EVT_MENU, self.OnSaveAs, id=2)
        self.Bind(wx.EVT_MENU, self.OnUploadButton, id=3)
        self.Bind(wx.EVT_MENU, self.OnVerifyButton, id=4)
        self.Bind(wx.EVT_MENU, self.OnMessageButton, id=5)

        self.Bind(wx.EVT_MENU, self.OnTimeToClose, id=wx.ID_EXIT)
        
        # and put the menu on the menubar
        
        menuBar.Append(self.filemenu, "&File")

        # the tweak menu 
        
        self.tweakmenu = wx.Menu()

        # create menu items
        
        self.tweakmenu.Append(10, "Wrap", "Wrap to 16 characters per line")
        self.tweakmenu.Append(11, "Center", "Center Lines")
       
        # bind to their actions
        
        self.Bind(wx.EVT_MENU, self.OnWrap, id=10)
        self.Bind(wx.EVT_MENU, self.OnCenter, id=11)

        # and put the menu on the menubar
        
        menuBar.Append(self.tweakmenu, "&Tweak")

        self.SetMenuBar(menuBar)

        self.CreateStatusBar()
        
        # create the panel that contains all the UI elements
        
        mainpanel = wx.Panel(self)
        
        mainpanelsizer = wx.BoxSizer(wx.VERTICAL)
        
        self.ed = editor.Editor(mainpanel, -1, style=wx.SUNKEN_BORDER)
        
        mainpanelsizer.Add(self.ed, 1, wx.ALL|wx.GROW, 1)
        mainpanel.SetSizer(mainpanelsizer)
        mainpanel.SetAutoLayout(True)


        self.ed.SetText(["Enter the text",
                    "you want the",
                    "SpokePOV to",
                    "display here.",
                    "",
                    "Keep in mind the",
                    "16 char per line",
                    "limit!"
                   ])
                    
        self.Wrap()
        self.Center()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -