1   
  2   
  3   
  4  import RPi.GPIO as GPIO 
  5  from time import sleep 
  6   
  7  PATTERN = b'\0\x86\x22\0\0\0\0\x02\0\0\0\0\x04\x40\x80\x52\x3f\x06\x5b\x4f\x66\x6d\x7d\x07\x7f\x6f\0\0\0\x48\0\0\x5d\x77\x7c\x39\x5e\x79\x71\x3d\x76\x30\x0e\x70\x38\x55\x54\x3f\x73\x67\x50\x2d\x78\x3e\x36\x6a\x49\x6e\x1b\x39\x64\x0f\x23\x08\x20\x77\x7c\x58\x5e\x79\x71\x3d\x74\x10\x0c\x70\x30\x55\x54\x5c\x73\x67\x50\x2d\x78\x1c\x36\x6a\x49\x6e\x1b\0\x30\0\x41' 
 10      ''' 
 11      Abstraction of the 4 digit 7-segment display based on the TM1637 display driver. 
 12      7-bit ASCII characters are mapped as close as possible to the 7 display segments. If a  
 13      character cannot be mapped, the digit is cleared. 
 14      ''' 
 15   
 16      myData = [0,0,0,0] 
 17       
 18      @staticmethod 
 20          ''' 
 21          Returns a string with all displayable characters taken from PATTERN dictionary. 
 22          @return: The character set that can be displayed 
 23          ''' 
 24          s = "<SPACE>" 
 25          k = 33 
 26          while k < 127: 
 27              ch = chr(k) 
 28              if TM1637.PATTERN[ch] != 0: 
 29                  s = s + ch 
 30              k += 1 
 31          return  s 
  32   
 33      @staticmethod 
 35          ''' 
 36          Returns a string with hex digits from given number (>0, any size). 
 37          @param number: the number to convert (must be positive) 
 38          @return: string of hex digits (uppercase), e.g. 0xFE 
 39          ''' 
 40          return '%02x' % intValue 
  41   
 42      @staticmethod 
 44          ''' 
 45          Returns a list of four byte values [byte#24-#31, byte#16-#23, byte#8-#15, byte#0-#7] of given integer. 
 46          @param number: an integer 
 47          @return: list with integers of 4 bytes [MSB,..., LSB] 
 48          ''' 
 49          byte0 = intValue & 0xff 
 50          byte1 = (intValue >> 8) & 0xff 
 51          byte2 = (intValue >> 16) & 0xff 
 52          byte3 = (intValue >> 24) & 0xff 
 53          return [byte3, byte2, byte1, byte0] 
  54   
 55      @staticmethod 
 57          ''' 
 58          Returns an integer from given hex string 
 59          @param number: a string with the number to convert, e.g. "FE" or "fe" or "0xFE" or "0XFE" 
 60          @return: integer number 
 61          ''' 
 62          return int(hexValue, 16) 
  63       
 64       
 65 -    def __init__(self, dio = 38, clk = 40, lum = 4): 
  66          ''' 
 67          Creates a display instance that uses the two given GPIO pins for data (dio, default: 38) and  
 68          clock (clk, default: 40). 
 69          It is set to the given luminosiy (0..9, default: 4) 
 70          ''' 
 71          GPIO.setmode(GPIO.BOARD) 
 72          GPIO.setwarnings(False) 
 73          self.clk = clk 
 74          self.dio = dio 
 75          self.lum = lum 
 76          self.colon = False 
 77          self.startPos = 0 
 78          self.text = None 
 79          GPIO.setup(clk, GPIO.OUT) 
 80          GPIO.setup(dio, GPIO.OUT) 
 81          GPIO.output(clk, 0) 
 82          GPIO.output(dio, 0) 
  83   
 84       
 86          ''' 
 87          Clears the display (all digits are turned off). 
 88          ''' 
 89          self.colon = False 
 90          self.show("    ") 
  91   
 92 -    def show(self, text, pos = 0): 
  93          ''' 
 94          Displays 4 characters of the given text. The text is considered to be prefixed and postfixed by spaces 
 95          and the 4 character window is selected by the text pointer pos that determines the character displayed at the 
 96          leftmost digit, e.g. (_: empty): 
 97          showText("AbCdEF") -> AbCd 
 98          showText("AbCdEF", 1) -> bCdE 
 99          showText("AbCdEF", -1) ->_AbC 
100          showText("AbCdEF", 4) -> EF__ 
101          @param text: the text to display (string or integer) 
102          @param pos: the start value of the text pointer (character index positioned a leftmost digit) 
103          ''' 
104          self.startPos = pos 
105          self.pos = pos 
106          self.text = str(text)   
107          if len(self.text) < 4: 
108              self.text = "%-4s" % self.text 
109          self._cropText() 
 110           
120               
122          ''' 
123          Scrolls the current text one step to the left by decreasing the text pointer. 
124          @return: the number of characters hidden, but remaining to be displayed at the left (>=0); -1, if error 
125          ''' 
126          if self.text == None: 
127              return -1 
128          self.pos -= 1     
129          self._cropText() 
130          return max(0, 4 + self.pos) 
 131   
133          ''' 
134          Scrolls the current text one step to the left by increasing the text pointer. 
135          @return: the number of characters hidden, but remaining to be displayed at the right (>=0); -1, if error 
136          ''' 
137          if self.text == None: 
138              return -1 
139          self.pos += 1     
140          self._cropText() 
141          nb = len(self.text) - self.pos 
142          return max(0, nb) 
 143   
145          ''' 
146          Shows the text at the start position by setting the text pointer to its start value. 
147          ''' 
148          if self.text == None: 
149              return -1 
150          self.pos = self.startPos     
151          self._cropText() 
 152          
154          ''' 
155          Sets the brightness of the display. 
156          @param luminosity the brightness (0..9, 0: invisible) 
157          ''' 
158          self.lum = lum 
 159   
161          ''' 
162          Enables/disables the colon in the middle of the screen. 
163          @param enable if True, the colon is shown in all subsequent text operations 
164          ''' 
165          self.colon = enable 
 166           
167       
168   
169 -    def _cropText(self): 
 170          n = len(self.text) 
171          data = [' '] * (n + 8) 
172          for i in range(n): 
173              data[i + 4] = self.text[i] 
174          start = max(0, self.pos + 4) 
175          start = min(start, len(data) - 4) 
176          end = min(start + n, len(data)) 
177          data = self._toSegment(data[start:end]) 
178          self._prepare(0x40)     
179          self._writeByte(0xC0) 
180          for i in range(4): 
181              self._writeByte(data[i]) 
182          self._commit() 
 183           
185          for i in range(8): 
186              GPIO.output(self.clk, 0) 
187              sleep(0.0001) 
188              if data & 0x01: 
189                  GPIO.output(self.dio, 1) 
190              else: 
191                  GPIO.output(self.dio, 0) 
192              sleep(0.0001) 
193              data = data >> 1 
194              GPIO.output(self.clk, 1) 
195              sleep(0.0001) 
196   
197          GPIO.output(self.clk, 0) 
198          GPIO.output(self.dio, 1) 
199          GPIO.output(self.clk, 1) 
200           
201          while GPIO.input(self.dio) == 1: 
202              sleep(0.001) 
203          sleep(0.001) 
 204       
206          data = [] 
207          msb = 0 
208          if self.colon: 
209              msb = 0x80 
210          for c in text: 
211              if ord(c) < 32 or ord(c) > 127: 
212                  c = " " 
213              data.append(ord(PATTERN[ord(c) - 32]) + msb) 
214          return data 
 215   
217          GPIO.output(self.clk, 1) 
218          GPIO.output(self.dio, 1) 
219          sleep(0.0001) 
220          GPIO.output(self.dio, 0)  
221          GPIO.output(self.clk, 0)  
222          sleep(0.0001) 
 223       
225          GPIO.output(self.clk, 0)  
226          GPIO.output(self.dio, 0)  
227          sleep(0.0001) 
228          GPIO.output(self.clk, 1) 
229          GPIO.output(self.dio, 1) 
230          sleep(0.0001) 
 231           
233          self._start() 
234          self._writeByte(addr) 
235          self._stop() 
236          self._start() 
237   
239          self._stop() 
240          self._start() 
241          self._writeByte(0x88 + self.lum) 
242          self._stop() 
 243