Files
clocky/tm1637.py
2019-09-24 16:44:24 +02:00

280 lines
7.6 KiB
Python

import math
import RPi.GPIO as IO
import threading
from time import sleep, localtime
# from tqdm import tqdm
# IO.setwarnings(False)
IO.setmode(IO.BCM)
HexDigits = [0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d,
0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x49, 0x50 ]
# 0 1 2 3 4 5 6
# 7 8 9 A B C D E F = r
# 10 11 12 13 14 15 16 17
#
# 0
# ---
# | |
# 5 | 7 | 1
# ---
# | |
# 4 | | 2
# ---
# 3
#
ADDR_AUTO = 0x40
ADDR_FIXED = 0x44
STARTADDR = 0xC0
# DEBUG = False
class TM1637:
__doublePoint = False
__Clkpin = 0
__Datapin = 0
__brightness = 1.0 # default to max brightness
__currentData = [0, 0, 0, 0]
def __init__(self, CLK, DIO, brightness):
self.__Clkpin = CLK
self.__Datapin = DIO
self.__brightness = brightness
IO.setup(self.__Clkpin, IO.OUT)
IO.setup(self.__Datapin, IO.OUT)
def cleanup(self):
"""Stop updating clock, turn off display, and cleanup GPIO"""
IO.cleanup()
def Clear(self):
b = self.__brightness
point = self.__doublePoint
self.__brightness = 0
self.__doublePoint = False
data = [0x7F, 0x7F, 0x7F, 0x7F]
self.Show(data)
# Restore previous settings:
self.__brightness = b
self.__doublePoint = point
def ShowInt(self, i):
s = str(i)
self.Clear()
for i in range(0, len(s)):
self.Show1(i, int(s[i]))
def Show(self, data):
for i in range(0, 4):
self.__currentData[i] = data[i]
self.start()
self.writeByte(ADDR_AUTO)
self.br()
self.writeByte(STARTADDR)
for i in range(0, 4):
self.writeByte(self.coding(data[i]))
self.br()
self.writeByte(0x88 + int(self.__brightness))
self.stop()
def Show1(self, DigitNumber, data):
"""show one Digit (number 0...3)"""
if(DigitNumber < 0 or DigitNumber > 3):
return # error
self.__currentData[DigitNumber] = data
self.start()
self.writeByte(ADDR_FIXED)
self.br()
self.writeByte(STARTADDR | DigitNumber)
self.writeByte(self.coding(data))
self.br()
self.writeByte(0x88 + int(self.__brightness))
self.stop()
def SetBrightness(self, percent):
"""Accepts percent brightness from 0 - 1"""
max_brightness = 7.0
brightness = math.ceil(max_brightness * percent)
if (brightness < 0):
brightness = 0
if(self.__brightness != brightness):
self.__brightness = brightness
self.Show(self.__currentData)
def SetBrightnessRaw(self, brightness):
"""Accepts raw brightness from 0 - 7"""
if(self.__brightness != brightness):
self.__brightness = brightness
self.Show(self.__currentData)
def ShowDoublepoint(self, on):
"""Show or hide double point divider"""
if(self.__doublePoint != on):
self.__doublePoint = on
self.Show(self.__currentData)
def writeByte(self, data):
for i in range(0, 8):
IO.output(self.__Clkpin, IO.LOW)
if(data & 0x01):
IO.output(self.__Datapin, IO.HIGH)
else:
IO.output(self.__Datapin, IO.LOW)
data = data >> 1
IO.output(self.__Clkpin, IO.HIGH)
# wait for ACK
IO.output(self.__Clkpin, IO.LOW)
IO.output(self.__Datapin, IO.HIGH)
IO.output(self.__Clkpin, IO.HIGH)
IO.setup(self.__Datapin, IO.IN)
while(IO.input(self.__Datapin)):
sleep(0.001)
if(IO.input(self.__Datapin)):
IO.setup(self.__Datapin, IO.OUT)
IO.output(self.__Datapin, IO.LOW)
IO.setup(self.__Datapin, IO.IN)
IO.setup(self.__Datapin, IO.OUT)
def start(self):
"""send start signal to TM1637"""
IO.output(self.__Clkpin, IO.HIGH)
IO.output(self.__Datapin, IO.HIGH)
IO.output(self.__Datapin, IO.LOW)
IO.output(self.__Clkpin, IO.LOW)
def stop(self):
IO.output(self.__Clkpin, IO.LOW)
IO.output(self.__Datapin, IO.LOW)
IO.output(self.__Clkpin, IO.HIGH)
IO.output(self.__Datapin, IO.HIGH)
def br(self):
"""terse break"""
self.stop()
self.start()
def coding(self, data):
if(self.__doublePoint):
pointData = 0x80
else:
pointData = 0
if(data == 0x7F):
data = 0
else:
data = HexDigits[data] + pointData
return data
def clock(self, military_time):
"""Clock script modified from:
https://github.com/johnlr/raspberrypi-tm1637"""
self.ShowDoublepoint(True)
while (not self.__stop_event.is_set()):
t = localtime()
hour = t.tm_hour
if not military_time:
hour = 12 if (t.tm_hour % 12) == 0 else t.tm_hour % 12
d0 = hour // 10 if hour // 10 else 0
d1 = hour % 10
d2 = t.tm_min // 10
d3 = t.tm_min % 10
digits = [d0, d1, d2, d3]
self.Show(digits)
# # Optional visual feedback of running alarm:
# print digits
# for i in tqdm(range(60 - t.tm_sec)):
for i in range(60 - t.tm_sec):
if (not self.__stop_event.is_set()):
sleep(1)
def StartClock(self, military_time=True):
# Stop event based on: http://stackoverflow.com/a/6524542/3219667
self.__stop_event = threading.Event()
self.__clock_thread = threading.Thread(
target=self.clock, args=(military_time,))
self.__clock_thread.start()
def StopClock(self):
try:
print 'Attempting to stop live clock'
self.__stop_event.set()
except:
print 'No clock to close'
if __name__ == "__main__":
"""Confirm the display operation"""
display = TM1637(CLK=14, DIO=4, brightness=1.0)
display.Clear()
digits = [1, 2, 3, 4]
display.Show(digits)
print "1234 - Working? (Press Key)"
scrap = raw_input()
print "Updating one digit at a time:"
display.Clear()
display.Show1(1, 3)
sleep(0.5)
display.Show1(2, 2)
sleep(0.5)
display.Show1(3, 1)
sleep(0.5)
display.Show1(0, 4)
print "4321 - (Press Key)"
scrap = raw_input()
print "Add double point\n"
display.ShowDoublepoint(True)
sleep(0.2)
print "Brightness Off"
display.SetBrightness(0)
sleep(0.5)
print "Full Brightness"
display.SetBrightness(1)
sleep(0.5)
print "30% Brightness"
display.SetBrightness(0.3)
sleep(0.3)
display.ShowDoublepoint(False)
display.Show1(0,0x7f);
display.Show1(1,14);
display.Show1(2,17);
display.Show1(3,17);
# See clock.py for how to use the clock functions!
display.SetBrightnessRaw(0)
print "level=0"
scrap=raw_input()
display.SetBrightnessRaw(1)
print "level=1"
scrap=raw_input()
display.SetBrightnessRaw(2)
print "level=2"
scrap=raw_input()
display.SetBrightnessRaw(3)
print "level=3"
scrap=raw_input()
display.SetBrightnessRaw(4)
print "level=4"
scrap=raw_input()
display.SetBrightnessRaw(5)
print "level=5"
scrap=raw_input()
display.SetBrightnessRaw(6)
print "level=6"
scrap=raw_input()
display.SetBrightnessRaw(7)
print "level=7"
scrap=raw_input()