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