Hyungsun Yoon

[HW] Add TM1637 and Reed sensor support

1 +"""
2 +MicroPython TM1637 quad 7-segment LED display driver
3 +https://github.com/mcauser/micropython-tm1637
4 +MIT License
5 +Copyright (c) 2016 Mike Causer
6 +Permission is hereby granted, free of charge, to any person obtaining a copy
7 +of this software and associated documentation files (the "Software"), to deal
8 +in the Software without restriction, including without limitation the rights
9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 +copies of the Software, and to permit persons to whom the Software is
11 +furnished to do so, subject to the following conditions:
12 +The above copyright notice and this permission notice shall be included in all
13 +copies or substantial portions of the Software.
14 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 +SOFTWARE.
21 +"""
22 +
23 +from micropython import const
24 +from machine import Pin
25 +from time import sleep_us, sleep_ms
26 +
27 +TM1637_CMD1 = const(64) # 0x40 data command
28 +TM1637_CMD2 = const(192) # 0xC0 address command
29 +TM1637_CMD3 = const(128) # 0x80 display control command
30 +TM1637_DSP_ON = const(8) # 0x08 display on
31 +TM1637_DELAY = const(10) # 10us delay between clk/dio pulses
32 +TM1637_MSB = const(128) # msb is the decimal point or the colon depending on your display
33 +
34 +# 0-9, a-z, blank, dash, star
35 +_SEGMENTS = bytearray(b'\x3F\x06\x5B\x4F\x66\x6D\x7D\x07\x7F\x6F\x77\x7C\x39\x5E\x79\x71\x3D\x76\x06\x1E\x76\x38\x55\x54\x3F\x73\x67\x50\x6D\x78\x3E\x1C\x2A\x76\x6E\x5B\x00\x40\x63')
36 +
37 +class TM1637(object):
38 + """Library for quad 7-segment LED modules based on the TM1637 LED driver."""
39 + def __init__(self, clk, dio, brightness=7):
40 + self.clk = clk
41 + self.dio = dio
42 +
43 + if not 0 <= brightness <= 7:
44 + raise ValueError("Brightness out of range")
45 + self._brightness = brightness
46 +
47 + self.clk.init(Pin.OUT, value=0)
48 + self.dio.init(Pin.OUT, value=0)
49 + sleep_us(TM1637_DELAY)
50 +
51 + self._write_data_cmd()
52 + self._write_dsp_ctrl()
53 +
54 + def _start(self):
55 + self.dio(0)
56 + sleep_us(TM1637_DELAY)
57 + self.clk(0)
58 + sleep_us(TM1637_DELAY)
59 +
60 + def _stop(self):
61 + self.dio(0)
62 + sleep_us(TM1637_DELAY)
63 + self.clk(1)
64 + sleep_us(TM1637_DELAY)
65 + self.dio(1)
66 +
67 + def _write_data_cmd(self):
68 + # automatic address increment, normal mode
69 + self._start()
70 + self._write_byte(TM1637_CMD1)
71 + self._stop()
72 +
73 + def _write_dsp_ctrl(self):
74 + # display on, set brightness
75 + self._start()
76 + self._write_byte(TM1637_CMD3 | TM1637_DSP_ON | self._brightness)
77 + self._stop()
78 +
79 + def _write_byte(self, b):
80 + for i in range(8):
81 + self.dio((b >> i) & 1)
82 + sleep_us(TM1637_DELAY)
83 + self.clk(1)
84 + sleep_us(TM1637_DELAY)
85 + self.clk(0)
86 + sleep_us(TM1637_DELAY)
87 + self.clk(0)
88 + sleep_us(TM1637_DELAY)
89 + self.clk(1)
90 + sleep_us(TM1637_DELAY)
91 + self.clk(0)
92 + sleep_us(TM1637_DELAY)
93 +
94 + def brightness(self, val=None):
95 + """Set the display brightness 0-7."""
96 + # brightness 0 = 1/16th pulse width
97 + # brightness 7 = 14/16th pulse width
98 + if val is None:
99 + return self._brightness
100 + if not 0 <= val <= 7:
101 + raise ValueError("Brightness out of range")
102 +
103 + self._brightness = val
104 + self._write_data_cmd()
105 + self._write_dsp_ctrl()
106 +
107 + def write(self, segments, pos=0):
108 + """Display up to 6 segments moving right from a given position.
109 + The MSB in the 2nd segment controls the colon between the 2nd
110 + and 3rd segments."""
111 + if not 0 <= pos <= 5:
112 + raise ValueError("Position out of range")
113 + self._write_data_cmd()
114 + self._start()
115 +
116 + self._write_byte(TM1637_CMD2 | pos)
117 + for seg in segments:
118 + self._write_byte(seg)
119 + self._stop()
120 + self._write_dsp_ctrl()
121 +
122 + def encode_digit(self, digit):
123 + """Convert a character 0-9, a-f to a segment."""
124 + return _SEGMENTS[digit & 0x0f]
125 +
126 + def encode_string(self, string):
127 + """Convert an up to 4 character length string containing 0-9, a-z,
128 + space, dash, star to an array of segments, matching the length of the
129 + source string."""
130 + segments = bytearray(len(string))
131 + for i in range(len(string)):
132 + segments[i] = self.encode_char(string[i])
133 + return segments
134 +
135 + def encode_char(self, char):
136 + """Convert a character 0-9, a-z, space, dash or star to a segment."""
137 + o = ord(char)
138 + if o == 32:
139 + return _SEGMENTS[36] # space
140 + if o == 42:
141 + return _SEGMENTS[38] # star/degrees
142 + if o == 45:
143 + return _SEGMENTS[37] # dash
144 + if o >= 65 and o <= 90:
145 + return _SEGMENTS[o-55] # uppercase A-Z
146 + if o >= 97 and o <= 122:
147 + return _SEGMENTS[o-87] # lowercase a-z
148 + if o >= 48 and o <= 57:
149 + return _SEGMENTS[o-48] # 0-9
150 + raise ValueError("Character out of range: {:d} '{:s}'".format(o, chr(o)))
151 +
152 + def hex(self, val):
153 + """Display a hex value 0x0000 through 0xffff, right aligned."""
154 + string = '{:04x}'.format(val & 0xffff)
155 + self.write(self.encode_string(string))
156 +
157 + def number(self, num):
158 + """Display a numeric value -999 through 9999, right aligned."""
159 + # limit to range -999 to 9999
160 + num = max(-999, min(num, 9999))
161 + string = '{0: >4d}'.format(num)
162 + self.write(self.encode_string(string))
163 +
164 + def numbers(self, num1, num2, colon=True):
165 + """Display two numeric values -9 through 99, with leading zeros
166 + and separated by a colon."""
167 + num1 = max(-9, min(num1, 99))
168 + num2 = max(-9, min(num2, 99))
169 + segments = self.encode_string('{0:0>2d}{1:0>2d}'.format(num1, num2))
170 + if colon:
171 + segments[1] |= 0x80 # colon on
172 + self.write(segments)
173 +
174 + def temperature(self, num):
175 + if num < -9:
176 + self.show('lo') # low
177 + elif num > 99:
178 + self.show('hi') # high
179 + else:
180 + string = '{0: >2d}'.format(num)
181 + self.write(self.encode_string(string))
182 + self.write([_SEGMENTS[38], _SEGMENTS[12]], 2) # degrees C
183 +
184 + def show(self, string, colon=False):
185 + segments = self.encode_string(string)
186 + if len(segments) > 1 and colon:
187 + segments[1] |= 128
188 + self.write(segments[:4])
189 +
190 + def scroll(self, string, delay=250):
191 + segments = string if isinstance(string, list) else self.encode_string(string)
192 + data = [0] * 8
193 + data[4:0] = list(segments)
194 + for i in range(len(segments) + 5):
195 + self.write(data[0+i:4+i])
196 + sleep_ms(delay)
197 +
198 +
199 +class TM1637Decimal(TM1637):
200 + """Library for quad 7-segment LED modules based on the TM1637 LED driver.
201 + This class is meant to be used with decimal display modules (modules
202 + that have a decimal point after each 7-segment LED).
203 + """
204 +
205 + def encode_string(self, string):
206 + """Convert a string to LED segments.
207 + Convert an up to 4 character length string containing 0-9, a-z,
208 + space, dash, star and '.' to an array of segments, matching the length of
209 + the source string."""
210 + segments = bytearray(len(string.replace('.','')))
211 + j = 0
212 + for i in range(len(string)):
213 + if string[i] == '.' and j > 0:
214 + segments[j-1] |= TM1637_MSB
215 + continue
216 + segments[j] = self.encode_char(string[i])
217 + j += 1
218 + return segments
1 +import tm1637
2 +from machine import Pin
3 +from utime import sleep
4 +display4 = tm1637.TM1637(clk=Pin(12), dio=Pin(13))
5 +
6 +# --------------------------------------------------- #
7 +# FUNCTIONS
8 +# --------------------------------------------------- #
9 +def work_tm1637(data:str):
10 + display4.show(data)
11 + sleep(2)
12 + mydisplay.show(' ')
13 +
14 +# # Show a word
15 +# mydisplay.show("Pico")
16 +# sleep(1)
17 +
18 +# #blank the screen
19 +# mydisplay.show(" ")
20 +# sleep(1)
21 +
22 +# #show numbers
23 +# mydisplay.number(-123)
24 +# sleep(1)
25 +
26 +# #show a time with colon
27 +# mydisplay.numbers(12,59)
28 +# sleep(1)
29 +
30 +# #adjust the brightness to make it lower
31 +# mydisplay.brightness(0)
32 +# sleep(1)
33 +
34 +# #show scrolling text
35 +# mydisplay.scroll("Hello World 123", delay=200)
36 +# sleep(1)
37 +
38 +# #show temperature
39 +# mydisplay.temperature(99)
40 +# sleep(1)
41 +
42 +# #blank the screen again
43 +# mydisplay.show(" ")
...\ No newline at end of file ...\ No newline at end of file
...@@ -6,39 +6,57 @@ import neopixel ...@@ -6,39 +6,57 @@ import neopixel
6 import dht 6 import dht
7 import bluetoooth as bto 7 import bluetoooth as bto
8 import ultrasonic 8 import ultrasonic
9 +import reed
10 +import display4
9 11
10 # --------------------------------------------------- # 12 # --------------------------------------------------- #
11 -# INIT 13 +# LOOP ENTRYPOINT
12 -# --------------------------------------------------- #
13 -
14 -
15 -# --------------------------------------------------- #
16 -# ENTRYPOINT
17 # --------------------------------------------------- # 14 # --------------------------------------------------- #
18 def _run(): 15 def _run():
16 + # INIT REED STATE
17 + reed_data = -1
18 + # LOOP
19 while True: 19 while True:
20 + # ------------------------------------------- #
21 + # DEFAULT LOOP
22 + # ------------------------------------------- #
23 + # Get data using BT(Standby)
20 input_data = bto.recv_data_bt() 24 input_data = bto.recv_data_bt()
21 - if input_data != '': 25 +
26 + # Get reed data from reed sensor
27 + current_reed_data = reed.work_reed()
28 +
29 + # ------------------------------------------- #
30 + # IF CONDITION MET
31 + # ------------------------------------------- #
32 + if input_data != '' or reed_data != current_reed_data:
33 + # Refine BT data
22 input_data = input_data.strip() 34 input_data = input_data.strip()
35 + # Test code
23 print('INPUT FOUND ', input_data) 36 print('INPUT FOUND ', input_data)
24 - print(len(input_data)) 37 +
25 - if input_data == 'A': 38 + # IF INPUT MEANS GET MESSAGE or MEDICINE LID STATUS CHANGED
26 - neopixel.work_led(0.2) 39 + if input_data == 'REQ' or reed_data != current_reed_data:
27 - elif input_data == 'B': 40 + # Collect Humidity, Temperature
28 dht_data = dht.work_dht() 41 dht_data = dht.work_dht()
29 if dht_data == False: 42 if dht_data == False:
30 - print("ERROR: DHT22 NOT WORKING") 43 + dht_data = [0,0]
31 - else: 44 + # Collect Ultrasonic distance
32 - print("INFO: HUMI ", dht_data[0]) 45 + ultrasonic_data = ultrasonic.work_sr04()
33 - print("INFO: TEMP ", dht_data[1]) 46 + # Make data string
34 - send_string = str(dht_data[0]) + ',' + str(dht_data[1]) 47 + send_data_str = str(reed_data) + '/' + str(dht_data[1]) + '/' + str(dht_data[0]) + '/' + str(ultrasonic_data)
35 - print(send_string) 48 + # Send data using BT
36 - bto.send_data_bt(send_string) 49 + bto.send_data_bt(send_data_str)
37 - elif input_data == 'C': 50 +
38 - ultasonic_data = ultrasonic.work_sr04()
39 - bto.send_data_bt(str(ultasonic_data))
40 else: 51 else:
41 - print('WRONG INPUT') 52 + # Refine BT data
53 + input_data = input_data.strip()
54 + display4.work_tm1637(input_data)
55 +
56 + # Update reed state
57 + reed_data = current_reed_data
58 +
59 +
42 60
43 if __name__ == '__main__': 61 if __name__ == '__main__':
44 _run() 62 _run()
...\ No newline at end of file ...\ No newline at end of file
......
1 +from machine import Pin, Signal
2 +
3 +data_pin = Pin(16, Pin.IN)
4 +
5 +# --------------------------------------------------- #
6 +# FUNCTIONS
7 +# --------------------------------------------------- #
8 +def work_reed() -> int:
9 + # 1 = Lid opened, 0 = Lid closed
10 + return data_pin.value()