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