Showing
4 changed files
with
311 additions
and
22 deletions
hardware/rpi_pico/TM1637.py
0 → 100644
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 |
hardware/rpi_pico/display4.py
0 → 100644
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 | ... | ... |
hardware/rpi_pico/reed.py
0 → 100644
-
Please register or login to post a comment