Showing
11 changed files
with
554 additions
and
3 deletions
... | @@ -12,3 +12,4 @@ | ... | @@ -12,3 +12,4 @@ |
12 | + 2021.05.12: RaspberryPi Pico v0.1 code complete. Now working on rpi4 with MQTT. | 12 | + 2021.05.12: RaspberryPi Pico v0.1 code complete. Now working on rpi4 with MQTT. |
13 | + 2021.05.13: RaspberryPi4 v0.1 code complete. with MQTT. + Pico code bug fix. | 13 | + 2021.05.13: RaspberryPi4 v0.1 code complete. with MQTT. + Pico code bug fix. |
14 | + 2021.05.13: Fritzing design add. | 14 | + 2021.05.13: Fritzing design add. |
15 | ++ 2021.05.16: RPI4 Code update | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -60,10 +60,20 @@ def _work_mqtt(client, userdata, msg): | ... | @@ -60,10 +60,20 @@ def _work_mqtt(client, userdata, msg): |
60 | 60 | ||
61 | # 만약 req메시지를 받았다면 | 61 | # 만약 req메시지를 받았다면 |
62 | if received_msg == 'req': | 62 | if received_msg == 'req': |
63 | + # 데이터가 손실되어 왔을 경우 에러 처리 | ||
64 | + if len(data_list[0]) == 0: | ||
65 | + data_list = [] | ||
66 | + elif len(data_list[3]) == 0: | ||
67 | + data_list = [] | ||
63 | while len(data_list) != 4: | 68 | while len(data_list) != 4: |
64 | _send_data('REQ') | 69 | _send_data('REQ') |
65 | data = _recv_data() | 70 | data = _recv_data() |
66 | data_list = data.split('/') | 71 | data_list = data.split('/') |
72 | + # 데이터가 손실되어 왔을 경우 에러 처리 | ||
73 | + if len(data_list[0]) == 0: | ||
74 | + data_list = [] | ||
75 | + elif len(data_list[3]) == 0: | ||
76 | + data_list = [] | ||
67 | # 데이터를 Publish한다 | 77 | # 데이터를 Publish한다 |
68 | _pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost') | 78 | _pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost') |
69 | 79 | ||
... | @@ -72,12 +82,23 @@ def _work_mqtt(client, userdata, msg): | ... | @@ -72,12 +82,23 @@ def _work_mqtt(client, userdata, msg): |
72 | _send_data(received_msg.split('/')[1]) | 82 | _send_data(received_msg.split('/')[1]) |
73 | data = _recv_data() | 83 | data = _recv_data() |
74 | data_list = data.split('/') | 84 | data_list = data.split('/') |
85 | + # 데이터가 손실되어 왔을 경우 에러 처리 | ||
86 | + if len(data_list[0]) == 0: | ||
87 | + data_list = [] | ||
88 | + elif len(data_list[3]) == 0: | ||
89 | + data_list = [] | ||
90 | + | ||
75 | while len(data_list) != 4: | 91 | while len(data_list) != 4: |
76 | _send_data('REQ') | 92 | _send_data('REQ') |
77 | data = _recv_data() | 93 | data = _recv_data() |
78 | data_list = data.split('/') | 94 | data_list = data.split('/') |
95 | + # 데이터가 손실되어 왔을 경우 에러 처리 | ||
96 | + if len(data_list[0]) == 0: | ||
97 | + data_list = [] | ||
98 | + elif len(data_list[3]) == 0: | ||
99 | + data_list = [] | ||
79 | # 데이터를 Publish한다 | 100 | # 데이터를 Publish한다 |
80 | - _pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost') | 101 | + # _pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost') |
81 | 102 | ||
82 | print("DEBUG") | 103 | print("DEBUG") |
83 | print(data) | 104 | print(data) |
... | @@ -119,10 +140,21 @@ def _run(): | ... | @@ -119,10 +140,21 @@ def _run(): |
119 | print('DATA IN') | 140 | print('DATA IN') |
120 | data_list = data.split('/') | 141 | data_list = data.split('/') |
121 | 142 | ||
143 | + # 데이터가 손실되어 왔을 경우 에러 처리 | ||
144 | + if len(data_list[0]) == 0: | ||
145 | + data_list = [] | ||
146 | + elif len(data_list[3]) == 0: | ||
147 | + data_list = [] | ||
148 | + | ||
122 | # 만약 데이터가 불량하게 왔을 경우, 제대로 올때까지 반복시도한다 | 149 | # 만약 데이터가 불량하게 왔을 경우, 제대로 올때까지 반복시도한다 |
123 | while len(data_list) != 4: | 150 | while len(data_list) != 4: |
124 | data = _recv_data() | 151 | data = _recv_data() |
125 | data_list = data.split('/') | 152 | data_list = data.split('/') |
153 | + # 데이터가 손실되어 왔을 경우 에러 처리 | ||
154 | + if len(data_list[0]) == 0: | ||
155 | + data_list = [] | ||
156 | + elif len(data_list[3]) == 0: | ||
157 | + data_list = [] | ||
126 | 158 | ||
127 | # 데이터를 Publish한다 | 159 | # 데이터를 Publish한다 |
128 | _pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost') | 160 | _pub_mqtt(f'bottle/{MED_BOTT_NO}/bts', data, 'localhost') | ... | ... |
... | @@ -53,7 +53,7 @@ def _run(): | ... | @@ -53,7 +53,7 @@ def _run(): |
53 | # IF INPUT MEANS GET MESSAGE or MEDICINE LID STATUS CHANGED | 53 | # IF INPUT MEANS GET MESSAGE or MEDICINE LID STATUS CHANGED |
54 | if input_data == 'REQ' or reed_data != current_reed_data: | 54 | if input_data == 'REQ' or reed_data != current_reed_data: |
55 | # Send data using BT | 55 | # Send data using BT |
56 | - bto.send_data_bt(_collect_sensor_datas(reed_data)) | 56 | + bto.send_data_bt(_collect_sensor_datas(current_reed_data)) |
57 | else: | 57 | else: |
58 | # Refine BT data | 58 | # Refine BT data |
59 | input_data = input_data.strip() | 59 | input_data = input_data.strip() |
... | @@ -61,7 +61,7 @@ def _run(): | ... | @@ -61,7 +61,7 @@ def _run(): |
61 | neopixel.work_led() | 61 | neopixel.work_led() |
62 | display4.off_tm1637() | 62 | display4.off_tm1637() |
63 | # Send data using BT | 63 | # Send data using BT |
64 | - bto.send_data_bt(_collect_sensor_datas(reed_data)) | 64 | + bto.send_data_bt(_collect_sensor_datas(current_reed_data)) |
65 | 65 | ||
66 | # Update reed state | 66 | # Update reed state |
67 | reed_data = current_reed_data | 67 | reed_data = current_reed_data | ... | ... |
hardware/rpi_pico_backup.py/bluetoooth.py
0 → 100644
1 | +import uos | ||
2 | +import machine | ||
3 | +import utime | ||
4 | + | ||
5 | +uart0 = machine.UART(0,baudrate=9600) | ||
6 | + | ||
7 | +def _clartBuf(uart=uart0): | ||
8 | + print("Clear UART buffer "+ str(uart)) | ||
9 | + while uart.any(): | ||
10 | + print(uart.read(1)) | ||
11 | + | ||
12 | + | ||
13 | +def send_data_bt(sdata:str): | ||
14 | + _clartBuf() | ||
15 | + uart0.write(sdata) | ||
16 | + | ||
17 | + | ||
18 | +def recv_data_bt(): | ||
19 | + _clartBuf() | ||
20 | + prvMills = utime.ticks_ms() | ||
21 | + received_data = '' | ||
22 | + | ||
23 | + while (utime.ticks_ms()-prvMills)<2000: | ||
24 | + if uart0.any(): | ||
25 | + single_data = uart0.read(1) | ||
26 | + received_data += single_data.decode('utf-8') | ||
27 | + | ||
28 | + return received_data |
hardware/rpi_pico_backup.py/dht.py
0 → 100644
1 | +import utime | ||
2 | +import rp2 | ||
3 | +from rp2 import PIO, asm_pio | ||
4 | +from machine import Pin | ||
5 | + | ||
6 | +dht_pwr = Pin(14, Pin.OUT) #connect GPIO 14 to '+' on DHT11 | ||
7 | +dht_data = Pin(15, Pin.IN, Pin.PULL_UP) #connect GPIO 15 to 'out' on DHT11 | ||
8 | + | ||
9 | +dht_pwr.value(1) #power on DHT11 | ||
10 | +sm=rp2.StateMachine(1) #create empty state machine | ||
11 | +utime.sleep(2) #wait for DHT11 to start up | ||
12 | + | ||
13 | +@asm_pio(set_init=(PIO.OUT_HIGH),autopush=True, push_thresh=8) #output one byte at a time | ||
14 | +def DHT22(): | ||
15 | + #drive output low for at least 20ms | ||
16 | + set(pindirs,1) #set pin to output | ||
17 | + set(pins,0) #set pin low | ||
18 | + set(y,31) #prepare countdown, y*x*100cycles | ||
19 | + label ('waity') | ||
20 | + set(x,31) | ||
21 | + label ('waitx') | ||
22 | + nop() [30] | ||
23 | + jmp(x_dec,'waitx') #decrement x reg every 100 cycles | ||
24 | + jmp(y_dec,'waity') #decrement y reg every time x reaches zero | ||
25 | + | ||
26 | + #begin reading from device | ||
27 | + set(pindirs,0) #set pin to input | ||
28 | + wait(1,pin,0) #check pin is high before starting | ||
29 | + wait(0,pin,0) | ||
30 | + wait(1,pin,0) | ||
31 | + wait(0,pin,0) #wait for start of data | ||
32 | + | ||
33 | + #read databit | ||
34 | + label('readdata') | ||
35 | + set(x,21) #reset x register to count down from 20 | ||
36 | + wait(1,pin,0) #wait for high signal | ||
37 | + label('countdown') | ||
38 | + jmp(pin,'continue') #if pin still high continue counting | ||
39 | + #pin is low before countdown is complete - bit '0' detected | ||
40 | + set(y,0) | ||
41 | + in_(y, 1) #shift '0' into the isr | ||
42 | + jmp('readdata') #read the next bit | ||
43 | + | ||
44 | + label('continue') | ||
45 | + jmp(x_dec,'countdown') #decrement x reg and continue counting if x!=0 | ||
46 | + #pin is still high after countdown complete - bit '1' detected | ||
47 | + set(y,1) | ||
48 | + in_(y, 1) #shift one bit into the isr | ||
49 | + wait(0,pin,0) #wait for low signal (next bit) | ||
50 | + jmp('readdata') #read the next bit | ||
51 | + | ||
52 | + | ||
53 | +# --------------------------------------------------- # | ||
54 | +# ENTRYPOINT | ||
55 | +# --------------------------------------------------- # | ||
56 | +def work_dht(): | ||
57 | + print("DHT22 WORKING") | ||
58 | + data=[] | ||
59 | + total=0 | ||
60 | + sm.init(DHT22,freq=1600000,set_base=dht_data,in_base=dht_data,jmp_pin=dht_data) #start state machine | ||
61 | + #state machine frequency adjusted so that PIO countdown during 'readdata' ends somewhere between the | ||
62 | + #duration of a '0' and a '1' high signal | ||
63 | + sm.active(1) | ||
64 | + for i in range(5): #data should be 40 bits (5 bytes) long | ||
65 | + data.append(sm.get()) #read byte | ||
66 | + | ||
67 | + print("data: " + str(data)) | ||
68 | + | ||
69 | + #check checksum (lowest 8 bits of the sum of the first 4 bytes) | ||
70 | + for i in range(4): | ||
71 | + total=total+data[i] | ||
72 | + if((total & 255) == data[4]): | ||
73 | + humidity=((data[0]<<8) + data[1])/10.0 #DHT11 provides integer humidity (no decimal part) | ||
74 | + temperature=(((data[2] &0x7f) << 8) + data[3]) /10.0 #DHT11 provides signed integer temperature (no decimal part) | ||
75 | + if (data[2] & 0x80) == 0x80: | ||
76 | + temperature = -temperature | ||
77 | + return [humidity, temperature] | ||
78 | + else: | ||
79 | + return False |
hardware/rpi_pico_backup.py/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 | + | ||
12 | +def off_tm1637(): | ||
13 | + display4.show(' ') |
hardware/rpi_pico_backup.py/main.py
0 → 100644
1 | +import array, utime | ||
2 | +from machine import Pin | ||
3 | +import rp2 | ||
4 | + | ||
5 | +import neopixel | ||
6 | +import dht | ||
7 | +import bluetoooth as bto | ||
8 | +import ultrasonic | ||
9 | +import reed | ||
10 | +import display4 | ||
11 | + | ||
12 | +# --------------------------------------------------- # | ||
13 | +# FUNCTIONS | ||
14 | +# --------------------------------------------------- # | ||
15 | +def _collect_sensor_datas(reed_data:int) -> str: | ||
16 | + # Collect Humidity, Temperature | ||
17 | + dht_data = dht.work_dht() | ||
18 | + if dht_data == False: | ||
19 | + dht_data = [0,0] | ||
20 | + # Collect Ultrasonic distance | ||
21 | + ultrasonic_data = ultrasonic.work_sr04() | ||
22 | + # Make data string | ||
23 | + send_data_str = str(reed_data) + '/' + str(dht_data[1]) + '/' + str(dht_data[0]) + '/' + str(ultrasonic_data) | ||
24 | + | ||
25 | + return send_data_str | ||
26 | + | ||
27 | +# --------------------------------------------------- # | ||
28 | +# LOOP ENTRYPOINT | ||
29 | +# --------------------------------------------------- # | ||
30 | +def _run(): | ||
31 | + # INIT REED STATE | ||
32 | + reed_data = -1 | ||
33 | + display4.off_tm1637() | ||
34 | + # LOOP | ||
35 | + while True: | ||
36 | + # ------------------------------------------- # | ||
37 | + # DEFAULT LOOP | ||
38 | + # ------------------------------------------- # | ||
39 | + # Get data using BT(Standby) | ||
40 | + input_data = bto.recv_data_bt() | ||
41 | + | ||
42 | + # Get reed data from reed sensor | ||
43 | + current_reed_data = reed.work_reed() | ||
44 | + | ||
45 | + # ------------------------------------------- # | ||
46 | + # IF CONDITION MET | ||
47 | + # ------------------------------------------- # | ||
48 | + if input_data != '' or reed_data != current_reed_data: | ||
49 | + # Refine BT data | ||
50 | + input_data = input_data.strip() | ||
51 | + # Test code | ||
52 | + print('INPUT FOUND ', input_data) | ||
53 | + | ||
54 | + # IF INPUT MEANS GET MESSAGE or MEDICINE LID STATUS CHANGED | ||
55 | + if input_data == 'REQ' or reed_data != current_reed_data: | ||
56 | + # Send data using BT | ||
57 | + bto.send_data_bt(_collect_sensor_datas(reed_data)) | ||
58 | + else: | ||
59 | + # Refine BT data | ||
60 | + input_data = input_data.strip() | ||
61 | + display4.work_tm1637(input_data) | ||
62 | + neopixel.work_led() | ||
63 | + display4.off_tm1637() | ||
64 | + # Send data using BT | ||
65 | + bto.send_data_bt(_collect_sensor_datas(reed_data)) | ||
66 | + | ||
67 | + # Update reed state | ||
68 | + reed_data = current_reed_data | ||
69 | + | ||
70 | + | ||
71 | + | ||
72 | +if __name__ == '__main__': | ||
73 | + _run() |
hardware/rpi_pico_backup.py/neopixel.py
0 → 100644
1 | +import array, utime | ||
2 | +from machine import Pin | ||
3 | +import rp2 | ||
4 | + | ||
5 | +NUM_LEDS = 8 | ||
6 | +PIN_NUM = 22 | ||
7 | + | ||
8 | +BLACK = (0, 0, 0) | ||
9 | +RED = (255, 0, 0) | ||
10 | +YELLOW = (255, 150, 0) | ||
11 | +GREEN = (0, 255, 0) | ||
12 | +CYAN = (0, 255, 255) | ||
13 | +BLUE = (0, 0, 255) | ||
14 | +PURPLE = (180, 0, 255) | ||
15 | +WHITE = (255, 255, 255) | ||
16 | +COLORS = (BLACK, RED, YELLOW, GREEN, CYAN, BLUE, PURPLE, WHITE, BLACK) | ||
17 | + | ||
18 | +@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24) | ||
19 | +def ws2812(): | ||
20 | + T1 = 2 | ||
21 | + T2 = 5 | ||
22 | + T3 = 3 | ||
23 | + wrap_target() | ||
24 | + label("bitloop") | ||
25 | + out(x, 1) .side(0) [T3 - 1] | ||
26 | + jmp(not_x, "do_zero") .side(1) [T1 - 1] | ||
27 | + jmp("bitloop") .side(1) [T2 - 1] | ||
28 | + label("do_zero") | ||
29 | + nop() .side(0) [T2 - 1] | ||
30 | + wrap() | ||
31 | + | ||
32 | +# Create the StateMachine with the ws2812 program, outputting on pin | ||
33 | +sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(PIN_NUM)) | ||
34 | +# Start the StateMachine, it will wait for data on its FIFO. | ||
35 | +sm.active(1) | ||
36 | +# Display a pattern on the LEDs via an array of LED RGB values. | ||
37 | +ar = array.array("I", [0 for _ in range(NUM_LEDS)]) | ||
38 | + | ||
39 | +# --------------------------------------------------- # | ||
40 | +# FUNCTIONS | ||
41 | +# --------------------------------------------------- # | ||
42 | +def _pixels_show(brightness:int = 0.2): | ||
43 | + dimmer_ar = array.array("I", [0 for _ in range(NUM_LEDS)]) | ||
44 | + for i,c in enumerate(ar): | ||
45 | + r = int(((c >> 8) & 0xFF) * brightness) | ||
46 | + g = int(((c >> 16) & 0xFF) * brightness) | ||
47 | + b = int((c & 0xFF) * brightness) | ||
48 | + dimmer_ar[i] = (g<<16) + (r<<8) + b | ||
49 | + sm.put(dimmer_ar, 8) | ||
50 | + utime.sleep_ms(10) | ||
51 | + | ||
52 | +def _pixels_set(i, color): | ||
53 | + ar[i] = (color[1]<<16) + (color[0]<<8) + color[2] | ||
54 | + | ||
55 | +def _pixels_fill(color): | ||
56 | + for i in range(len(ar)): | ||
57 | + _pixels_set(i, color) | ||
58 | + | ||
59 | + | ||
60 | +# --------------------------------------------------- # | ||
61 | +# ENTRYPOINT | ||
62 | +# --------------------------------------------------- # | ||
63 | +def work_led(brightness:int = 0.2): | ||
64 | + print("WS2812B WORKING") | ||
65 | + for color in COLORS: | ||
66 | + _pixels_fill(color) | ||
67 | + _pixels_show(brightness) | ||
68 | + utime.sleep(0.4) | ||
69 | + |
hardware/rpi_pico_backup.py/reed.py
0 → 100644
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() | ||
11 | + |
hardware/rpi_pico_backup.py/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 | ||
219 | + | ||
220 | + |
hardware/rpi_pico_backup.py/ultrasonic.py
0 → 100644
1 | +''' Original code from https://www.iottrends.tech/blog/how-to-use-ultrasonic-sensor-with-raspberry-pi-pico/ | ||
2 | +''' | ||
3 | +from machine import Pin | ||
4 | +import utime | ||
5 | +trigger = Pin(26, Pin.OUT) | ||
6 | +echo = Pin(27, Pin.IN) | ||
7 | + | ||
8 | +# --------------------------------------------------- # | ||
9 | +# FUNCTIONS | ||
10 | +# --------------------------------------------------- # | ||
11 | +def work_sr04(): | ||
12 | + trigger.low() | ||
13 | + utime.sleep_us(2) | ||
14 | + trigger.high() | ||
15 | + utime.sleep_us(5) | ||
16 | + trigger.low() | ||
17 | + while echo.value() == 0: | ||
18 | + signaloff = utime.ticks_us() | ||
19 | + while echo.value() == 1: | ||
20 | + signalon = utime.ticks_us() | ||
21 | + timepassed = signalon - signaloff | ||
22 | + distance = (timepassed * 0.0330) / 2 | ||
23 | + | ||
24 | + return distance | ||
25 | + |
-
Please register or login to post a comment