docs: 同步日常维护指南并补齐遗漏的板卡配置
This commit is contained in:
BIN
mixly/boards/HDK/MixGo CC-V3.2.pdf
Normal file
BIN
mixly/boards/HDK/MixGo CC-V3.2.pdf
Normal file
Binary file not shown.
BIN
mixly/boards/HDK/MixGo CE-V3.7.pdf
Normal file
BIN
mixly/boards/HDK/MixGo CE-V3.7.pdf
Normal file
Binary file not shown.
BIN
mixly/boards/HDK/MixGo ME-V2.3.pdf
Normal file
BIN
mixly/boards/HDK/MixGo ME-V2.3.pdf
Normal file
Binary file not shown.
BIN
mixly/boards/HDK/MixGo Nova-V2.6.pdf
Normal file
BIN
mixly/boards/HDK/MixGo Nova-V2.6.pdf
Normal file
Binary file not shown.
BIN
mixly/boards/HDK/MixGo_MINI-V1.7.pdf
Normal file
BIN
mixly/boards/HDK/MixGo_MINI-V1.7.pdf
Normal file
Binary file not shown.
BIN
mixly/boards/default/micropython/build/HZK12.bin
Normal file
BIN
mixly/boards/default/micropython/build/HZK12.bin
Normal file
Binary file not shown.
BIN
mixly/boards/default/micropython/build/HZK16.bin
Normal file
BIN
mixly/boards/default/micropython/build/HZK16.bin
Normal file
Binary file not shown.
BIN
mixly/boards/default/micropython/build/HZK16_GBK.bin
Normal file
BIN
mixly/boards/default/micropython/build/HZK16_GBK.bin
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
602
mixly/boards/default/micropython/build/lib/adafruit_miniqr.py
Normal file
602
mixly/boards/default/micropython/build/lib/adafruit_miniqr.py
Normal file
@@ -0,0 +1,602 @@
|
||||
# SPDX-FileCopyrightText: 2009 Kazuhiko Arase
|
||||
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# Ported from the Javascript library by Sam Curren
|
||||
# QRCode for Javascript
|
||||
# http://d-project.googlecode.com/svn/trunk/misc/qrcode/js/qrcode.js
|
||||
#
|
||||
# Minimized for CircuitPython by ladyada for adafruit industries
|
||||
#
|
||||
# The word "QR Code" is registered trademark of
|
||||
# DENSO WAVE INCORPORATED
|
||||
# http://www.denso-wave.com/qrcode/faqpatent-e.html
|
||||
"""
|
||||
`adafruit_miniqr`
|
||||
====================================================
|
||||
|
||||
A non-hardware dependant miniature QR generator library. All native Python!
|
||||
|
||||
* Author(s): ladyada
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
|
||||
**Hardware:**
|
||||
|
||||
* Any!
|
||||
|
||||
**Software and Dependencies:**
|
||||
|
||||
* Python 3
|
||||
|
||||
"""
|
||||
|
||||
# imports
|
||||
import math
|
||||
|
||||
try:
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
__version__ = "0.0.0+auto.0"
|
||||
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_miniQR.git"
|
||||
|
||||
# Consts!
|
||||
M = 0
|
||||
L = 1
|
||||
H = 2
|
||||
Q = 3
|
||||
|
||||
_MODE_8BIT_BYTE = 1 << 2
|
||||
_PAD0 = 0xEC
|
||||
_PAD1 = 0x11
|
||||
|
||||
# Optimized polynomial helpers
|
||||
|
||||
|
||||
def _glog(n: int) -> int:
|
||||
"""Lookup log(n) from pre-calculated byte table"""
|
||||
if n < 1:
|
||||
raise ValueError("glog(" + n + ")")
|
||||
return LOG_TABLE[n]
|
||||
|
||||
|
||||
def _gexp(n: int) -> int:
|
||||
"""Lookup exp(n) from pre-calculated byte table"""
|
||||
while n < 0:
|
||||
n += 255
|
||||
while n >= 256:
|
||||
n -= 255
|
||||
return EXP_TABLE[n]
|
||||
|
||||
|
||||
EXP_TABLE = b"\x01\x02\x04\x08\x10 @\x80\x1d:t\xe8\xcd\x87\x13&L\x98-Z\xb4u\xea\xc9\x8f\x03\x06\x0c\x180`\xc0\x9d'N\x9c%J\x945j\xd4\xb5w\xee\xc1\x9f#F\x8c\x05\n\x14(P\xa0]\xbai\xd2\xb9o\xde\xa1_\xbea\xc2\x99/^\xbce\xca\x89\x0f\x1e<x\xf0\xfd\xe7\xd3\xbbk\xd6\xb1\x7f\xfe\xe1\xdf\xa3[\xb6q\xe2\xd9\xafC\x86\x11\"D\x88\r\x1a4h\xd0\xbdg\xce\x81\x1f>|\xf8\xed\xc7\x93;v\xec\xc5\x973f\xcc\x85\x17.\\\xb8m\xda\xa9O\x9e!B\x84\x15*T\xa8M\x9a)R\xa4U\xaaI\x929r\xe4\xd5\xb7s\xe6\xd1\xbfc\xc6\x91?~\xfc\xe5\xd7\xb3{\xf6\xf1\xff\xe3\xdb\xabK\x961b\xc4\x957n\xdc\xa5W\xaeA\x82\x192d\xc8\x8d\x07\x0e\x1c8p\xe0\xdd\xa7S\xa6Q\xa2Y\xb2y\xf2\xf9\xef\xc3\x9b+V\xacE\x8a\t\x12$H\x90=z\xf4\xf5\xf7\xf3\xfb\xeb\xcb\x8b\x0b\x16,X\xb0}\xfa\xe9\xcf\x83\x1b6l\xd8\xadG\x8e\x01" # noqa: E501
|
||||
|
||||
LOG_TABLE = b"\x00\x00\x01\x19\x022\x1a\xc6\x03\xdf3\xee\x1bh\xc7K\x04d\xe0\x0e4\x8d\xef\x81\x1c\xc1i\xf8\xc8\x08Lq\x05\x8ae/\xe1$\x0f!5\x93\x8e\xda\xf0\x12\x82E\x1d\xb5\xc2}j'\xf9\xb9\xc9\x9a\txM\xe4r\xa6\x06\xbf\x8bbf\xdd0\xfd\xe2\x98%\xb3\x10\x91\"\x886\xd0\x94\xce\x8f\x96\xdb\xbd\xf1\xd2\x13\\\x838F@\x1eB\xb6\xa3\xc3H~nk:(T\xfa\x85\xba=\xca^\x9b\x9f\n\x15y+N\xd4\xe5\xacs\xf3\xa7W\x07p\xc0\xf7\x8c\x80c\rgJ\xde\xed1\xc5\xfe\x18\xe3\xa5\x99w&\xb8\xb4|\x11D\x92\xd9# \x89.7?\xd1[\x95\xbc\xcf\xcd\x90\x87\x97\xb2\xdc\xfc\xbea\xf2V\xd3\xab\x14*]\x9e\x84<9SGmA\xa2\x1f-C\xd8\xb7{\xa4v\xc4\x17I\xec\x7f\x0co\xf6l\xa1;R)\x9dU\xaa\xfb`\x86\xb1\xbb\xcc>Z\xcbY_\xb0\x9c\xa9\xa0Q\x0b\xf5\x16\xebzu,\xd7O\xae\xd5\xe9\xe6\xe7\xad\xe8t\xd6\xf4\xea\xa8PX\xaf" # noqa: E501
|
||||
|
||||
|
||||
class QRCode:
|
||||
"""The generator class for QR code matrices"""
|
||||
|
||||
def __init__(self, *, qr_type: Optional[int] = None, error_correct: int = L):
|
||||
"""Initialize an empty QR code. You can define the `qr_type` (size)
|
||||
of the code matrix, or have the libary auto-select the smallest
|
||||
match. Default `error_correct` is type L (7%), but you can select M,
|
||||
Q or H."""
|
||||
self.type = qr_type
|
||||
self.ECC = error_correct
|
||||
self.matrix = None
|
||||
self.module_count = 0
|
||||
self.data_cache = None
|
||||
self.data_list = []
|
||||
|
||||
def add_data(self, data: bytes) -> None:
|
||||
"""Add more data to the QR code, must be bytestring stype"""
|
||||
self.data_list.append(data)
|
||||
datalen = sum(len(x) for x in self.data_list)
|
||||
if not self.type:
|
||||
for qr_type in range(1, 10):
|
||||
rs_blocks = _get_rs_blocks(qr_type, self.ECC)
|
||||
total_data_count = 0
|
||||
for block in rs_blocks:
|
||||
total_data_count += block["data"]
|
||||
if total_data_count > datalen:
|
||||
self.type = qr_type
|
||||
break
|
||||
self.data_cache = None
|
||||
|
||||
def make(self, *, test: bool = False, mask_pattern: int = 0) -> None:
|
||||
"""Perform the actual generation of the QR matrix. To keep things
|
||||
small and speedy we don't generate all 8 mask patterns and pick
|
||||
the best. Instead, please pass in a desired mask_pattern, the
|
||||
default mask is 0."""
|
||||
self.module_count = self.type * 4 + 17
|
||||
self.matrix = QRBitMatrix(self.module_count, self.module_count)
|
||||
|
||||
self._setup_position_probe_pattern(0, 0)
|
||||
self._setup_position_probe_pattern(self.module_count - 7, 0)
|
||||
self._setup_position_probe_pattern(0, self.module_count - 7)
|
||||
self._setup_position_adjust_pattern()
|
||||
self._setup_timing_pattern()
|
||||
self._setup_type_info(test, mask_pattern)
|
||||
|
||||
if self.type >= 7:
|
||||
self._setup_type_number(test)
|
||||
|
||||
if self.data_cache is None:
|
||||
self.data_cache = QRCode._create_data(self.type, self.ECC, self.data_list)
|
||||
self._map_data(self.data_cache, mask_pattern)
|
||||
|
||||
def _setup_position_probe_pattern(self, row: int, col: int) -> None:
|
||||
"""Add the positition probe data pixels to the matrix"""
|
||||
for r in range(-1, 8):
|
||||
if row + r <= -1 or self.module_count <= row + r:
|
||||
continue
|
||||
for c in range(-1, 8):
|
||||
if col + c <= -1 or self.module_count <= col + c:
|
||||
continue
|
||||
test = (
|
||||
(0 <= r <= 6 and (c in (0, 6)))
|
||||
or (0 <= c <= 6 and (r in (0, 6)))
|
||||
or (2 <= r <= 4 and 2 <= c <= 4)
|
||||
)
|
||||
self.matrix[row + r, col + c] = test
|
||||
|
||||
def _setup_timing_pattern(self) -> None:
|
||||
"""Add the timing data pixels to the matrix"""
|
||||
for r in range(8, self.module_count - 8):
|
||||
if self.matrix[r, 6] is not None:
|
||||
continue
|
||||
self.matrix[r, 6] = r % 2 == 0
|
||||
|
||||
for c in range(8, self.module_count - 8):
|
||||
if self.matrix[6, c] is not None:
|
||||
continue
|
||||
self.matrix[6, c] = c % 2 == 0
|
||||
|
||||
def _setup_position_adjust_pattern(self) -> None:
|
||||
"""Add the position adjust data pixels to the matrix"""
|
||||
pos = QRUtil.get_pattern_position(self.type)
|
||||
|
||||
for row in pos:
|
||||
for col in pos:
|
||||
if self.matrix[row, col] is not None:
|
||||
continue
|
||||
|
||||
for r in range(-2, 3):
|
||||
for c in range(-2, 3):
|
||||
test = abs(r) == 2 or abs(c) == 2 or (r == 0 and c == 0)
|
||||
self.matrix[row + r, col + c] = test
|
||||
|
||||
def _setup_type_number(self, test: bool) -> None:
|
||||
"""Add the type number pixels to the matrix"""
|
||||
bits = QRUtil.get_BCH_type_number(self.type)
|
||||
|
||||
for i in range(18):
|
||||
mod = not test and ((bits >> i) & 1) == 1
|
||||
self.matrix[i // 3, i % 3 + self.module_count - 8 - 3] = mod
|
||||
|
||||
for i in range(18):
|
||||
mod = not test and ((bits >> i) & 1) == 1
|
||||
self.matrix[i % 3 + self.module_count - 8 - 3, i // 3] = mod
|
||||
|
||||
def _setup_type_info(self, test: bool, mask_pattern: int) -> None:
|
||||
"""Add the type info pixels to the matrix"""
|
||||
data = (self.ECC << 3) | mask_pattern
|
||||
bits = QRUtil.get_BCH_type_info(data)
|
||||
|
||||
# // vertical
|
||||
for i in range(15):
|
||||
mod = not test and ((bits >> i) & 1) == 1
|
||||
if i < 6:
|
||||
self.matrix[i, 8] = mod
|
||||
elif i < 8:
|
||||
self.matrix[i + 1, 8] = mod
|
||||
else:
|
||||
self.matrix[self.module_count - 15 + i, 8] = mod
|
||||
|
||||
# // horizontal
|
||||
for i in range(15):
|
||||
mod = not test and ((bits >> i) & 1) == 1
|
||||
if i < 8:
|
||||
self.matrix[8, self.module_count - i - 1] = mod
|
||||
elif i < 9:
|
||||
self.matrix[8, 15 - i - 1 + 1] = mod
|
||||
else:
|
||||
self.matrix[8, 15 - i - 1] = mod
|
||||
|
||||
# // fixed module
|
||||
self.matrix[self.module_count - 8, 8] = not test
|
||||
|
||||
def _map_data(self, data: bytes, mask_pattern: int) -> None:
|
||||
"""Map the data onto the QR code"""
|
||||
inc = -1
|
||||
row = self.module_count - 1
|
||||
bit_idx = 7
|
||||
byte_idx = 0
|
||||
|
||||
for col in range(self.module_count - 1, 0, -2):
|
||||
if col == 6:
|
||||
col -= 1 # noqa: PLW2901 loop variable overwritten
|
||||
|
||||
while True:
|
||||
for c in range(2):
|
||||
if self.matrix[row, col - c] is None:
|
||||
dark = False
|
||||
if byte_idx < len(data):
|
||||
dark = ((data[byte_idx] >> bit_idx) & 1) == 1
|
||||
mask = QRUtil.get_mask(mask_pattern, row, col - c)
|
||||
if mask:
|
||||
dark = not dark
|
||||
self.matrix[row, col - c] = dark
|
||||
bit_idx -= 1
|
||||
if bit_idx == -1:
|
||||
byte_idx += 1
|
||||
bit_idx = 7
|
||||
row += inc
|
||||
if row < 0 or self.module_count <= row:
|
||||
row -= inc
|
||||
inc = -inc
|
||||
break
|
||||
|
||||
@staticmethod
|
||||
def _create_data(qr_type: int, ecc: int, data_list: list) -> bytes:
|
||||
"""Check and format data into bit buffer"""
|
||||
rs_blocks = _get_rs_blocks(qr_type, ecc)
|
||||
|
||||
buffer = QRBitBuffer()
|
||||
|
||||
for data in data_list:
|
||||
if isinstance(data, str):
|
||||
data = str.encode(data) # noqa: PLW2901 loop variable overwritten
|
||||
buffer.put(_MODE_8BIT_BYTE, 4)
|
||||
buffer.put(len(data), 8)
|
||||
for byte in data:
|
||||
buffer.put(byte, 8)
|
||||
|
||||
# // calc num max data.
|
||||
total_data_count = 0
|
||||
for block in rs_blocks:
|
||||
total_data_count += block["data"]
|
||||
|
||||
if buffer.get_length_bits() > total_data_count * 8:
|
||||
raise RuntimeError(
|
||||
"Code length overflow: %d > %d" % (buffer.get_length_bits(), total_data_count * 8)
|
||||
)
|
||||
|
||||
# // end code
|
||||
if buffer.get_length_bits() + 4 <= total_data_count * 8:
|
||||
buffer.put(0, 4)
|
||||
|
||||
# // padding
|
||||
while buffer.get_length_bits() % 8 != 0:
|
||||
buffer.put_bit(False)
|
||||
|
||||
# // padding
|
||||
while True:
|
||||
if buffer.get_length_bits() >= total_data_count * 8:
|
||||
break
|
||||
buffer.put(_PAD0, 8)
|
||||
if buffer.get_length_bits() >= total_data_count * 8:
|
||||
break
|
||||
buffer.put(_PAD1, 8)
|
||||
|
||||
return QRCode._create_bytes(buffer, rs_blocks)
|
||||
|
||||
@staticmethod
|
||||
def _create_bytes(buffer: bytes, rs_blocks: List[Dict]) -> bytes: # noqa: PLR0912 Too many branches
|
||||
"""Perform error calculation math on bit buffer"""
|
||||
|
||||
offset = 0
|
||||
max_dc_count = 0
|
||||
max_ec_count = 0
|
||||
|
||||
dcdata = [0] * len(rs_blocks)
|
||||
ecdata = [0] * len(rs_blocks)
|
||||
|
||||
for r, block in enumerate(rs_blocks):
|
||||
dc_count = block["data"]
|
||||
ec_count = block["total"] - dc_count
|
||||
|
||||
max_dc_count = max(max_dc_count, dc_count)
|
||||
max_ec_count = max(max_ec_count, ec_count)
|
||||
|
||||
dcdata[r] = [0] * dc_count
|
||||
|
||||
for i in range(len(dcdata[r])):
|
||||
dcdata[r][i] = 0xFF & buffer.buffer[i + offset]
|
||||
offset += dc_count
|
||||
|
||||
rs_poly = QRUtil.get_error_correct_polynomial(ec_count)
|
||||
mod_poly = QRPolynomial(dcdata[r], rs_poly.get_length() - 1)
|
||||
|
||||
while True:
|
||||
if mod_poly.get_length() - rs_poly.get_length() < 0:
|
||||
break
|
||||
ratio = _glog(mod_poly.get(0)) - _glog(rs_poly.get(0))
|
||||
num = [0 for x in range(mod_poly.get_length())]
|
||||
for i in range(mod_poly.get_length()):
|
||||
num[i] = mod_poly.get(i)
|
||||
for i in range(rs_poly.get_length()):
|
||||
num[i] ^= _gexp(_glog(rs_poly.get(i)) + ratio)
|
||||
mod_poly = QRPolynomial(num, 0)
|
||||
|
||||
ecdata[r] = [0 for x in range(rs_poly.get_length() - 1)]
|
||||
for i in range(len(ecdata[r])):
|
||||
mod_index = i + mod_poly.get_length() - len(ecdata[r])
|
||||
if mod_index >= 0:
|
||||
ecdata[r][i] = mod_poly.get(mod_index)
|
||||
else:
|
||||
ecdata[r][i] = 0
|
||||
|
||||
total_code_count = 0
|
||||
for block in rs_blocks:
|
||||
total_code_count += block["total"]
|
||||
|
||||
data = [None] * total_code_count
|
||||
index = 0
|
||||
|
||||
for i in range(max_dc_count):
|
||||
for r in range(len(rs_blocks)):
|
||||
if i < len(dcdata[r]):
|
||||
data[index] = dcdata[r][i]
|
||||
index += 1
|
||||
|
||||
for i in range(max_ec_count):
|
||||
for r in range(len(rs_blocks)):
|
||||
if i < len(ecdata[r]):
|
||||
data[index] = ecdata[r][i]
|
||||
index += 1
|
||||
|
||||
return data
|
||||
|
||||
|
||||
class QRUtil:
|
||||
"""A selection of bit manipulation tools for QR generation and BCH encoding"""
|
||||
|
||||
PATTERN_POSITION_TABLE = [
|
||||
b"",
|
||||
b"\x06\x12",
|
||||
b"\x06\x16",
|
||||
b"\x06\x1a",
|
||||
b"\x06\x1e",
|
||||
b'\x06"',
|
||||
b"\x06\x16&",
|
||||
b"\x06\x18*",
|
||||
b"\x06\x1a.",
|
||||
b"\x06\x1c2",
|
||||
]
|
||||
|
||||
G15 = 0b10100110111
|
||||
G18 = 0b1111100100101
|
||||
G15_MASK = 0b101010000010010
|
||||
|
||||
@staticmethod
|
||||
def get_BCH_type_info(data: int) -> int:
|
||||
"""Encode with G15 BCH mask"""
|
||||
d = data << 10
|
||||
while QRUtil.get_BCH_digit(d) - QRUtil.get_BCH_digit(QRUtil.G15) >= 0:
|
||||
d ^= QRUtil.G15 << (QRUtil.get_BCH_digit(d) - QRUtil.get_BCH_digit(QRUtil.G15))
|
||||
|
||||
return ((data << 10) | d) ^ QRUtil.G15_MASK
|
||||
|
||||
@staticmethod
|
||||
def get_BCH_type_number(data: int) -> int:
|
||||
"""Encode with G18 BCH mask"""
|
||||
d = data << 12
|
||||
while QRUtil.get_BCH_digit(d) - QRUtil.get_BCH_digit(QRUtil.G18) >= 0:
|
||||
d ^= QRUtil.G18 << (QRUtil.get_BCH_digit(d) - QRUtil.get_BCH_digit(QRUtil.G18))
|
||||
return (data << 12) | d
|
||||
|
||||
@staticmethod
|
||||
def get_BCH_digit(data: int) -> int:
|
||||
"""Count digits in data"""
|
||||
digit = 0
|
||||
while data != 0:
|
||||
digit += 1
|
||||
data >>= 1
|
||||
return digit
|
||||
|
||||
@staticmethod
|
||||
def get_pattern_position(qr_type: int) -> bytes:
|
||||
"""The mask pattern position array for this QR type"""
|
||||
return QRUtil.PATTERN_POSITION_TABLE[qr_type - 1]
|
||||
|
||||
@staticmethod
|
||||
def get_mask(mask: int, i: int, j: int) -> int: # noqa: PLR0911 Too many return statements
|
||||
"""Perform matching calculation on two vals for given pattern mask"""
|
||||
if mask == 0:
|
||||
return (i + j) % 2 == 0
|
||||
if mask == 1:
|
||||
return i % 2 == 0
|
||||
if mask == 2:
|
||||
return j % 3 == 0
|
||||
if mask == 3:
|
||||
return (i + j) % 3 == 0
|
||||
if mask == 4:
|
||||
return (math.floor(i / 2) + math.floor(j / 3)) % 2 == 0
|
||||
if mask == 5:
|
||||
return (i * j) % 2 + (i * j) % 3 == 0
|
||||
if mask == 6:
|
||||
return ((i * j) % 2 + (i * j) % 3) % 2 == 0
|
||||
if mask == 7:
|
||||
return ((i * j) % 3 + (i + j) % 2) % 2 == 0
|
||||
raise ValueError("Bad mask pattern:" + mask)
|
||||
|
||||
@staticmethod
|
||||
def get_error_correct_polynomial(ecc_length: int) -> "QRPolynomial":
|
||||
"""Generate a ecc polynomial"""
|
||||
poly = QRPolynomial([1], 0)
|
||||
for i in range(ecc_length):
|
||||
poly = poly.multiply(QRPolynomial([1, _gexp(i)], 0))
|
||||
return poly
|
||||
|
||||
|
||||
class QRPolynomial:
|
||||
"""Structure for creating and manipulating error code polynomials"""
|
||||
|
||||
def __init__(self, num: int, shift: int):
|
||||
"""Create a QR polynomial"""
|
||||
if not num:
|
||||
raise ValueError(num.length + "/" + shift)
|
||||
offset = 0
|
||||
while offset < len(num) and num[offset] == 0:
|
||||
offset += 1
|
||||
self.num = [0 for x in range(len(num) - offset + shift)]
|
||||
for i in range(len(num) - offset):
|
||||
self.num[i] = num[i + offset]
|
||||
|
||||
def get(self, index: int) -> int:
|
||||
"""The exponent at the index location"""
|
||||
return self.num[index]
|
||||
|
||||
def get_length(self) -> int:
|
||||
"""Length of the poly"""
|
||||
return len(self.num)
|
||||
|
||||
def multiply(self, other_polynomial: "QRPolynomial") -> "QRPolynomial":
|
||||
"""Multiply two polynomials, returns a new one"""
|
||||
num = [0 for x in range(self.get_length() + other_polynomial.get_length() - 1)]
|
||||
|
||||
for i in range(self.get_length()):
|
||||
for j in range(other_polynomial.get_length()):
|
||||
num[i + j] ^= _gexp(_glog(self.get(i)) + _glog(other_polynomial.get(j)))
|
||||
|
||||
return QRPolynomial(num, 0)
|
||||
|
||||
|
||||
_QRRS_BLOCK_TABLE = (
|
||||
b"\x01\x1a\x10",
|
||||
b"\x01\x1a\x13",
|
||||
b"\x01\x1a\t",
|
||||
b"\x01\x1a\r",
|
||||
b"\x01,\x1c",
|
||||
b'\x01,"',
|
||||
b"\x01,\x10",
|
||||
b"\x01,\x16",
|
||||
b"\x01F,",
|
||||
b"\x01F7",
|
||||
b"\x02#\r",
|
||||
b"\x02#\x11",
|
||||
b"\x022 ",
|
||||
b"\x01dP",
|
||||
b"\x04\x19\t",
|
||||
b"\x022\x18",
|
||||
b"\x02C+",
|
||||
b"\x01\x86l",
|
||||
b'\x02!\x0b\x02"\x0c',
|
||||
b'\x02!\x0f\x02"\x10',
|
||||
b"\x04+\x1b",
|
||||
b"\x02VD",
|
||||
b"\x04+\x0f",
|
||||
b"\x04+\x13",
|
||||
b"\x041\x1f",
|
||||
b"\x02bN",
|
||||
b"\x04'\r\x01(\x0e",
|
||||
b"\x02 \x0e\x04!\x0f",
|
||||
b"\x02<&\x02='",
|
||||
b"\x02ya",
|
||||
b"\x04(\x0e\x02)\x0f",
|
||||
b"\x04(\x12\x02)\x13",
|
||||
b"\x03:$\x02;%",
|
||||
b"\x02\x92t",
|
||||
b"\x04$\x0c\x04%\r",
|
||||
b"\x04$\x10\x04%\x11",
|
||||
)
|
||||
|
||||
|
||||
def _get_rs_blocks(qr_type: int, ecc: int) -> List[Dict]:
|
||||
rs_block = _QRRS_BLOCK_TABLE[(qr_type - 1) * 4 + ecc]
|
||||
|
||||
length = len(rs_block) // 3
|
||||
blocks = []
|
||||
for i in range(length):
|
||||
count = rs_block[i * 3 + 0]
|
||||
total = rs_block[i * 3 + 1]
|
||||
data = rs_block[i * 3 + 2]
|
||||
block = {"total": total, "data": data}
|
||||
for _ in range(count):
|
||||
blocks.append(block)
|
||||
return blocks
|
||||
|
||||
|
||||
class QRBitMatrix:
|
||||
"""A bit-packed storage class for matrices"""
|
||||
|
||||
def __init__(self, width: int, height: int):
|
||||
self.width = width
|
||||
self.height = height
|
||||
if width > 60:
|
||||
raise ValueError("Max 60 bits wide:", width)
|
||||
self.buffer = [0] * self.height * 2
|
||||
self.used = [0] * self.height * 2
|
||||
|
||||
def __repr__(self) -> str:
|
||||
b = ""
|
||||
for y in range(self.height):
|
||||
for x in range(self.width):
|
||||
if self[x, y]:
|
||||
b += "X"
|
||||
else:
|
||||
b += "."
|
||||
b += "\n"
|
||||
return b
|
||||
|
||||
def __getitem__(self, key: Tuple[int, int]) -> int:
|
||||
x, y = key
|
||||
if y > self.width:
|
||||
raise ValueError()
|
||||
i = 2 * x + (y // 30)
|
||||
j = y % 30
|
||||
if not self.used[i] & (1 << j):
|
||||
return None
|
||||
return self.buffer[i] & (1 << j)
|
||||
|
||||
def __setitem__(self, key: Tuple[int, int], value: int) -> None:
|
||||
x, y = key
|
||||
if y > self.width:
|
||||
raise ValueError()
|
||||
i = 2 * x + (y // 30)
|
||||
j = y % 30
|
||||
if value:
|
||||
self.buffer[i] |= 1 << j
|
||||
else:
|
||||
self.buffer[i] &= ~(1 << j)
|
||||
self.used[i] |= 1 << j # buffer item was set
|
||||
|
||||
|
||||
class QRBitBuffer:
|
||||
"""Storage class for a length of individual bits"""
|
||||
|
||||
def __init__(self):
|
||||
self.buffer = []
|
||||
self.length = 0
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return ".".join([str(n) for n in self.buffer])
|
||||
|
||||
def get(self, index: int) -> int:
|
||||
"""The bit value at a location"""
|
||||
i = index // 8
|
||||
return self.buffer[i] & (1 << (7 - index % 8))
|
||||
|
||||
def put(self, num: int, length: int) -> None:
|
||||
"""Add a number of bits from a single integer value"""
|
||||
for i in range(length):
|
||||
self.put_bit(num & (1 << (length - i - 1)))
|
||||
|
||||
def get_length_bits(self) -> int:
|
||||
"""Size of bit buffer"""
|
||||
return self.length
|
||||
|
||||
def put_bit(self, bit: int) -> None:
|
||||
"""Insert one bit at the end of the bit buffer"""
|
||||
i = self.length // 8
|
||||
if len(self.buffer) <= i:
|
||||
self.buffer.append(0)
|
||||
if bit:
|
||||
self.buffer[i] |= 0x80 >> (self.length % 8)
|
||||
self.length += 1
|
||||
52
mixly/boards/default/micropython/build/lib/adxl345.py
Normal file
52
mixly/boards/default/micropython/build/lib/adxl345.py
Normal file
@@ -0,0 +1,52 @@
|
||||
#ADXL345
|
||||
import time
|
||||
import ustruct
|
||||
from micropython import const
|
||||
|
||||
DATA_FORMAT = const(0x31)
|
||||
BW_RATE = const(0x2c)
|
||||
POWER_CTL = const(0x2d)
|
||||
INT_ENABLE = const(0x2E)
|
||||
OFSX = const(0x1e)
|
||||
OFSY = const(0x1f)
|
||||
OFSZ = const(0x20)
|
||||
|
||||
class ADXL345:
|
||||
def __init__(self, i2c, address=0X53):
|
||||
self._device = i2c
|
||||
self._address = address
|
||||
if self._rreg(0x0) != 0xe5:
|
||||
raise AttributeError("Cannot find a ADXL345")
|
||||
|
||||
self._wreg(DATA_FORMAT,0x2B) #16g量程
|
||||
self._wreg(BW_RATE,0x0A) #数据输出速度为100Hz
|
||||
self._wreg(INT_ENABLE,0x00) #不使用中断
|
||||
|
||||
self._wreg(OFSX,0x00)
|
||||
self._wreg(OFSY,0x00)
|
||||
self._wreg(OFSZ,0x00)
|
||||
self._wreg(POWER_CTL,0x08) #链接使能,测量模式
|
||||
time.sleep(0.5)
|
||||
|
||||
def readXYZ(self):
|
||||
x, = ustruct.unpack('<h', self._rreg(0x32,2))
|
||||
y, = ustruct.unpack('<h', self._rreg(0x34,2))
|
||||
z, = ustruct.unpack('<h', self._rreg(0x36,2))
|
||||
return (x/256,y/256,z/256)
|
||||
|
||||
def readX(self):
|
||||
return self.readXYZ()[0]
|
||||
|
||||
def readY(self):
|
||||
return self.readXYZ()[1]
|
||||
|
||||
def readZ(self):
|
||||
return self.readXYZ()[2]
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg,nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
97
mixly/boards/default/micropython/build/lib/ags10.py
Normal file
97
mixly/boards/default/micropython/build/lib/ags10.py
Normal file
@@ -0,0 +1,97 @@
|
||||
"""
|
||||
AGS10
|
||||
|
||||
Micropython library for the AGS10(TVOC)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
_AGS10_ADC = const(0x00)
|
||||
_AGS10_CAL = const(0x01)
|
||||
_AGS10_RES = const(0x20)
|
||||
_AGS10_ADD = const(0x21)
|
||||
|
||||
class AGS10:
|
||||
def __init__(self, i2c_bus, address=0x1A, delay=1000):
|
||||
self._i2c = i2c_bus
|
||||
self._addr = address
|
||||
self._voc = 0
|
||||
self._delay = delay
|
||||
self._star = 0
|
||||
self.ready = 0
|
||||
|
||||
def _crc8(self, buf, is_byte=False):
|
||||
'''Perform CRC check on the data'''
|
||||
crc = 0xff
|
||||
for byte in buf:
|
||||
crc ^= byte
|
||||
for _ in range(8):
|
||||
if crc & 0x80:
|
||||
crc = (crc << 1) ^ 0x31
|
||||
else:
|
||||
crc = crc << 1
|
||||
return crc.to_bytes(1, 'little') if is_byte else crc & 0xff
|
||||
|
||||
def _wreg(self, reg, buf):
|
||||
'''Write memory address'''
|
||||
self._i2c.writeto_mem(self._addr, reg, buf)
|
||||
time.sleep_ms(20)
|
||||
|
||||
def _rreg(self, reg, nbytes=5):
|
||||
'''Read memory address'''
|
||||
_buf = self._i2c.readfrom_mem(self._addr, reg, nbytes)
|
||||
time.sleep_ms(20)
|
||||
return _buf[:4] if self._crc8(_buf[:4]) == _buf[4] else None
|
||||
|
||||
def address(self, addr=None):
|
||||
_scan = self._i2c.scan()
|
||||
if addr is None:
|
||||
if self._addr in _scan:
|
||||
return self._addr
|
||||
elif len(_scan) == 1:
|
||||
self._addr = _scan[0]
|
||||
return self._addr
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
if self.address():
|
||||
if 8<= addr <=119:
|
||||
_buf = bytes([addr, (~ addr) & 0xff] * 2)
|
||||
self._wreg(_AGS10_ADD, _buf + self._crc8(_buf, True))
|
||||
if addr in self._i2c.scan():
|
||||
self._addr = addr
|
||||
return True
|
||||
else:
|
||||
raise ValueError("Not within the valid range of 8-119")
|
||||
|
||||
def calibration(self, zero=1):
|
||||
'''0: Factory restoration 1:Sensor resistance'''
|
||||
_buf = b'\x00\x0c'
|
||||
_buf += b'\x00\x00' if zero else b'\xff\xff'
|
||||
self._wreg(_AGS10_ADD, _buf + self._crc8(_buf, True))
|
||||
|
||||
@property
|
||||
def getdata(self):
|
||||
if time.ticks_diff(time.ticks_ms(), self._star) >= self._delay:
|
||||
self._star = time.ticks_ms()
|
||||
_buf = self._rreg(_AGS10_ADC)
|
||||
self._voc = int.from_bytes(_buf[1:4], 'big')
|
||||
self.ready = not (_buf[0] & 0x01)
|
||||
return self._voc / 1000
|
||||
|
||||
def read(self, hcho_mw=30.033 , co2_mv=0.853, co2_base=400):
|
||||
'''unit ppm'''
|
||||
self.getdata
|
||||
_voc = self._voc / 1000 #ppm
|
||||
return round( _voc, 2), round( _voc / hcho_mw, 2), co2_base + round( _voc / co2_mv, 2)
|
||||
|
||||
def tvoc(self):
|
||||
return self.read()[0]
|
||||
|
||||
def hcho(self, tvoc_mw=30.053):
|
||||
return self.read(hcho_mw=hcho_mw)[1]
|
||||
|
||||
def eco2(self, co2_mv=0.853):
|
||||
return self.read(co2_mv=co2_mv)[2]
|
||||
88
mixly/boards/default/micropython/build/lib/ahtx0.py
Normal file
88
mixly/boards/default/micropython/build/lib/ahtx0.py
Normal file
@@ -0,0 +1,88 @@
|
||||
"""
|
||||
AHT21
|
||||
|
||||
Micropython library for the AHT21(temperature,humidity)
|
||||
=======================================================
|
||||
|
||||
#Changed from circuitpython to micropython 20220211
|
||||
#Format unified 20220623
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
import utime
|
||||
from micropython import const
|
||||
|
||||
AHTX0_I2CADDR_DEFAULT = const(0x38) # Default I2C address
|
||||
AHTX0_CMD_INITIALIZE = const(0xE1) # Initialization command
|
||||
AHTX0_CMD_TRIGGER = const(0xAC) # Trigger reading command
|
||||
AHTX0_CMD_SOFTRESET = const(0xBA) # Soft reset command
|
||||
AHTX0_STATUS_BUSY = const(0x80) # Status bit for busy
|
||||
AHTX0_STATUS_CALIBRATED = const(0x08) # Status bit for calibrated
|
||||
|
||||
class AHTx0:
|
||||
"""Interface library for AHT10/AHT20 temperature+humidity sensors"""
|
||||
def __init__(self, i2c, address=AHTX0_I2CADDR_DEFAULT):
|
||||
utime.sleep_ms(20) # 20ms delay to wake up
|
||||
self._i2c = i2c
|
||||
self._address = address
|
||||
self._buf = bytearray(6)
|
||||
self.reset()
|
||||
if not self.initialize():
|
||||
raise AttributeError("Cannot find a AHTx0")
|
||||
self._temp = None
|
||||
self._humidity = None
|
||||
|
||||
def reset(self):
|
||||
"""Perform a soft-reset of the AHT"""
|
||||
self._buf[0] = AHTX0_CMD_SOFTRESET
|
||||
self._i2c.writeto(self._address, self._buf[0:1])
|
||||
utime.sleep_ms(20) # 20ms delay to wake up
|
||||
|
||||
def initialize(self):
|
||||
"""Ask the sensor to self-initialize. Returns True on success, False otherwise"""
|
||||
self._buf[0] = AHTX0_CMD_INITIALIZE
|
||||
self._buf[1] = 0x08
|
||||
self._buf[2] = 0x00
|
||||
self._i2c.writeto(self._address, self._buf[0:3])
|
||||
self._wait_for_idle()
|
||||
if not self.status() & AHTX0_STATUS_CALIBRATED:
|
||||
return False
|
||||
return True
|
||||
|
||||
def status(self):
|
||||
"""The status byte initially returned from the sensor, see datasheet for details"""
|
||||
self._read_to_buffer()
|
||||
return self._buf[0]
|
||||
|
||||
def _read_to_buffer(self):
|
||||
self._i2c.readfrom_into(self._address, self._buf)
|
||||
|
||||
def _trigger_measurement(self):
|
||||
"""Internal function for triggering the AHT to read temp/humidity"""
|
||||
self._buf[0] = AHTX0_CMD_TRIGGER
|
||||
self._buf[1] = 0x33
|
||||
self._buf[2] = 0x00
|
||||
self._i2c.writeto(self._address, self._buf[0:3])
|
||||
|
||||
def _wait_for_idle(self):
|
||||
while self.status() & AHTX0_STATUS_BUSY:
|
||||
utime.sleep_ms(5)
|
||||
|
||||
def _perform_measurement(self):
|
||||
self._trigger_measurement()
|
||||
self._wait_for_idle()
|
||||
self._read_to_buffer()
|
||||
|
||||
def humidity(self):
|
||||
"""The measured relative humidity in percent."""
|
||||
self._perform_measurement()
|
||||
self._humidity = (self._buf[1] << 12) | (self._buf[2] << 4) | (self._buf[3] >> 4)
|
||||
self._humidity = (self._humidity * 100) / 0x100000
|
||||
return self._humidity
|
||||
|
||||
def temperature(self):
|
||||
"""The measured temperature in degrees Celcius."""
|
||||
self._perform_measurement()
|
||||
self._temp = ((self._buf[3] & 0xF) << 16) | (self._buf[4] << 8) | self._buf[5]
|
||||
self._temp = ((self._temp * 200.0) / 0x100000) - 50
|
||||
return self._temp
|
||||
59
mixly/boards/default/micropython/build/lib/ap3216c.py
Normal file
59
mixly/boards/default/micropython/build/lib/ap3216c.py
Normal file
@@ -0,0 +1,59 @@
|
||||
"""
|
||||
AP3216C
|
||||
|
||||
MicroPython library for the AP3216C(ALS,PS,IRS)
|
||||
=======================================================
|
||||
#Preliminary composition 20240630
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
AP3216_ADD = const(0x1E)
|
||||
AP_SYS_CMD = const(0x00)
|
||||
AP_DAT = const(0x0A)
|
||||
AP_ALS_CMD = const(0x10)
|
||||
AP_PS_CMD = const(0x20)
|
||||
AP_PS_LED = const(0x21)
|
||||
Resolution = 0.35
|
||||
|
||||
class AP3216C:
|
||||
def __init__(self, i2c_bus, addr=AP3216_ADD):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
self._wreg(AP_SYS_CMD, 0x04) # SW reset
|
||||
time.sleep_ms(100)
|
||||
self._wreg(AP_SYS_CMD, 0x03) # 011: ALS and PS+IR functions active
|
||||
self._wreg(AP_ALS_CMD, 0x00) # Range 1: 0 ~ 20661 Lux. Resolution = 0.35 lux/count.
|
||||
self._wreg(AP_PS_CMD, 0x09) # PS gain:10
|
||||
self._wreg(AP_PS_LED, 0x23) # PS LED pulse:10
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
@property
|
||||
def getdata(self):
|
||||
'''处理获取数据'''
|
||||
#buf = self._rreg(AP_DAT, 6)
|
||||
ir = (self._rreg(AP_DAT + 0) & 0x03) | self._rreg(AP_DAT + 1) << 2
|
||||
als= (self._rreg(AP_DAT + 2) | self._rreg(AP_DAT + 3) << 8) * Resolution
|
||||
ps = (self._rreg(AP_DAT + 4) & 0x0F) | (self._rreg(AP_DAT + 5) & 0x3F) << 4
|
||||
return round(als, 2), ir, ps
|
||||
|
||||
def als_vis(self):
|
||||
'''可见光Lux'''
|
||||
return self.getdata[0]
|
||||
|
||||
def als_ir(self):
|
||||
'''红外Lux'''
|
||||
return self.getdata[1]
|
||||
|
||||
def ps_nl(self):
|
||||
'''接近距离'''
|
||||
return self.getdata[2]
|
||||
294
mixly/boards/default/micropython/build/lib/apds9960.py
Normal file
294
mixly/boards/default/micropython/build/lib/apds9960.py
Normal file
@@ -0,0 +1,294 @@
|
||||
"""
|
||||
APDS9960`
|
||||
|
||||
MicroPython library for the APDS9960(Supports gesture, proximity, and color detection)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20220224
|
||||
#base on https://github.com/adafruit/Adafruit_CircuitPython_BusDevice 20220623
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
_DEVICE_ID = const(0xAB)
|
||||
_APDS9960_ENABLE = const(0x80)
|
||||
_APDS9960_ATIME = const(0x81)
|
||||
_APDS9960_PILT = const(0x89)
|
||||
_APDS9960_PIHT = const(0x8B)
|
||||
_APDS9960_PERS = const(0x8C)
|
||||
_APDS9960_CONTROL = const(0x8F)
|
||||
_APDS9960_ID = const(0x92)
|
||||
_APDS9960_STATUS = const(0x93)
|
||||
_APDS9960_CDATAL = const(0x94)
|
||||
_APDS9960_PDATA = const(0x9C)
|
||||
_APDS9960_GPENTH = const(0xA0)
|
||||
_APDS9960_GEXTH = const(0xA1)
|
||||
_APDS9960_GCONF1 = const(0xA2)
|
||||
_APDS9960_GCONF2 = const(0xA3)
|
||||
_APDS9960_GPULSE = const(0xA6)
|
||||
_APDS9960_GCONF4 = const(0xAB)
|
||||
_APDS9960_GFLVL = const(0xAE)
|
||||
_APDS9960_GSTATUS = const(0xAF)
|
||||
_APDS9960_AICLEAR = const(0xE7)
|
||||
_APDS9960_GFIFO_U = const(0xFC)
|
||||
_BIT_MASK_ENABLE_EN = const(0x01)
|
||||
_BIT_MASK_ENABLE_COLOR = const(0x02)
|
||||
_BIT_MASK_ENABLE_PROX = const(0x04)
|
||||
_BIT_MASK_ENABLE_PROX_INT = const(0x20)
|
||||
_BIT_MASK_ENABLE_GESTURE = const(0x40)
|
||||
_BIT_MASK_STATUS_AVALID = const(0x01)
|
||||
_BIT_MASK_STATUS_GINT = const(0x04)
|
||||
_BIT_MASK_GSTATUS_GFOV = const(0x02)
|
||||
_BIT_MASK_GCONF4_GFIFO_CLR = const(0x04)
|
||||
_BIT_POS_PERS_PPERS = const(4)
|
||||
_BIT_MASK_PERS_PPERS = const(0xF0)
|
||||
_BIT_POS_CONTROL_AGAIN = const(0)
|
||||
_BIT_MASK_CONTROL_AGAIN = const(3)
|
||||
_BIT_POS_CONTROL_PGAIN = const(2)
|
||||
_BIT_MASK_CONTROL_PGAIN = const(0x0C)
|
||||
_BIT_POS_GCONF2_GGAIN = const(5)
|
||||
_BIT_MASK_GCONF2_GGAIN = const(0x60)
|
||||
|
||||
class APDS9960:
|
||||
def __init__(self, i2c, address=0x39):
|
||||
self._device = i2c
|
||||
self._address = address
|
||||
self._select = [True,True,True]
|
||||
|
||||
if self._rreg(_APDS9960_ID) != _DEVICE_ID:
|
||||
raise AttributeError("Cannot find a APDS9960")
|
||||
|
||||
self.enable(True) # Re-enable sensor and wait 10ms for the power on delay to finish
|
||||
time.sleep(0.010)
|
||||
self._wreg(_APDS9960_GPENTH, 0x05) # Enter gesture engine at >= 5 proximity counts
|
||||
self._wreg(_APDS9960_GEXTH, 0x1E) # Exit gesture engine if all counts drop below 30
|
||||
self._wreg(_APDS9960_GCONF1, 0x82) # GEXPERS: 2 (4 cycles), GEXMSK: 0 (default) GFIFOTH: 2 (8 datasets)
|
||||
self._wreg(_APDS9960_GCONF2, 0x41) # GGAIN: 2 (4x), GLDRIVE: 100 mA (default), GWTIME: 1 (2.8ms)
|
||||
self._wreg(_APDS9960_GPULSE, 0x85) # GPULSE: 5 (6 pulses), GPLEN: 2 (16 us)
|
||||
self.color_integration_time(256) # ATIME: 256 (712ms color integration time, max count of 65535)
|
||||
|
||||
# method for reading and writing to I2C
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _writecmdonly(self, val):
|
||||
"""Writes a command and 0 bytes of data to the I2C device"""
|
||||
self._device.writeto(self._address,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg,nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _get_bit(self, reg, mask):
|
||||
"""Gets a single bit value from the I2C device's register"""
|
||||
return bool(self._rreg(reg) & mask)
|
||||
|
||||
def _set_bit(self, reg, mask, value):
|
||||
"""Sets a single bit value in the I2C device's register"""
|
||||
buf=self._rreg(reg)
|
||||
buf= buf | mask if value else buf & ~mask
|
||||
self._wreg(reg,buf)
|
||||
|
||||
def _set_bits(self, reg, pos, mask, value):
|
||||
"""Sets a multi-bit value in the I2C device's register"""
|
||||
buf=self._rreg(reg)
|
||||
buf = (buf & ~mask) | (value << pos)
|
||||
self._wreg(reg,buf)
|
||||
|
||||
def _color_data16(self, reg):
|
||||
"""Sends a command and reads 2 bytes of data from the I2C device"""
|
||||
buf = self._rreg(reg,2)
|
||||
return buf[1] << 8 | buf[0]
|
||||
|
||||
def enable(self, value):
|
||||
"""sensor is enabled"""
|
||||
self._set_bit(_APDS9960_ENABLE, _BIT_MASK_ENABLE_EN, value)
|
||||
|
||||
def enable_proximity(self, value):
|
||||
"""sensor's proximity engine is enabled."""
|
||||
self._set_bit(_APDS9960_ENABLE, _BIT_MASK_ENABLE_PROX, value)
|
||||
|
||||
def proximity_gain(self, value):
|
||||
"""""Proximity sensor gain value"""
|
||||
# proximity_gain" "Gain Multiplier" "Note"
|
||||
# 0, "1x", "Power-on Default"
|
||||
# 1, "2x", ""
|
||||
# 2, "4x", ""
|
||||
# 3, "8x", ""
|
||||
self._set_bits(_APDS9960_CONTROL, _BIT_POS_CONTROL_PGAIN, _BIT_MASK_CONTROL_PGAIN, value)
|
||||
|
||||
def enable_gesture(self, value):
|
||||
"""sensor's gesture engine is enabled"""
|
||||
self._set_bit(_APDS9960_ENABLE, _BIT_MASK_ENABLE_GESTURE, value)
|
||||
|
||||
def gesture_gain(self, value):
|
||||
"""Gesture mode gain value"""
|
||||
# "gesture_gain" "Gain Multiplier" "Note"
|
||||
# 0, "1x", "Power-on Default"
|
||||
# 1, "2x", ""
|
||||
# 2, "4x", "Driver Default"
|
||||
# 3, "8x", ""
|
||||
self._set_bits(_APDS9960_GCONF2, _BIT_POS_GCONF2_GGAIN, _BIT_MASK_GCONF2_GGAIN, value)
|
||||
|
||||
def enable_color(self, value):
|
||||
"""sensor's color/light engine is enabled"""
|
||||
self._set_bit(_APDS9960_ENABLE, _BIT_MASK_ENABLE_COLOR, value)
|
||||
|
||||
def color_gain(self, value):
|
||||
"""Color/light sensor gain value"""
|
||||
# "color_gain" "Gain Multiplier" "Note"
|
||||
# 0, "1x", "Power-on Default"
|
||||
# 1, "4x", "Driver Default"
|
||||
# 2, "16x", ""
|
||||
# 3, "64x", ""
|
||||
self._set_bits(_APDS9960_CONTROL, _BIT_POS_CONTROL_AGAIN, _BIT_MASK_CONTROL_AGAIN, value)
|
||||
|
||||
def color_integration_time(self, value):
|
||||
"""Color/light sensor gain"""
|
||||
# "color_integration_time" "Time" "Max Count" "Note"
|
||||
# 1, "2.78 ms", 1025, "Power-on Default"
|
||||
# 10, "27.8 ms", 10241, ""
|
||||
# 37, "103 ms", 37889, ""
|
||||
# 72, "200 ms", 65535, ""
|
||||
# 256, "712 ms", 65535, "Driver Default"
|
||||
self._wreg(_APDS9960_ATIME, 256 - value)
|
||||
|
||||
## PROXIMITY
|
||||
def proximity(self,gain=2):
|
||||
"""Proximity sensor data"""
|
||||
if self._select[0]:
|
||||
self._select=[False,True,True]
|
||||
self.enable_proximity(True)
|
||||
self.enable_gesture(False)
|
||||
self.enable_color(False)
|
||||
self.proximity_gain(gain)
|
||||
|
||||
return self._rreg(_APDS9960_PDATA)
|
||||
|
||||
## GESTURE
|
||||
def gesture(self,gain=3):
|
||||
"""Gesture sensor data"""
|
||||
# If FIFOs have overflowed we're already way too late, so clear those FIFOs and wait
|
||||
if self._select[1]:
|
||||
self._select=[True,False,True]
|
||||
self.enable_proximity(True)
|
||||
self.enable_gesture(True)
|
||||
self.enable_color(False)
|
||||
self.gesture_gain(gain)
|
||||
|
||||
if self._get_bit(_APDS9960_GSTATUS, _BIT_MASK_GSTATUS_GFOV):
|
||||
self._set_bit(_APDS9960_GCONF4, _BIT_MASK_GCONF4_GFIFO_CLR, True)
|
||||
wait_cycles = 0
|
||||
while ( not self._get_bit(_APDS9960_STATUS, _BIT_MASK_STATUS_GINT) and wait_cycles <= 30 ):
|
||||
time.sleep(0.003)
|
||||
wait_cycles += 1
|
||||
|
||||
frame = []
|
||||
datasets_available = self._rreg(_APDS9960_GFLVL)
|
||||
if (self._get_bit(_APDS9960_STATUS, _BIT_MASK_STATUS_GINT) and datasets_available > 0 ):
|
||||
|
||||
buffer = bytearray(128)
|
||||
buffer_dataset = bytearray(4)
|
||||
while True:
|
||||
dataset_count = self._rreg(_APDS9960_GFLVL)
|
||||
if dataset_count == 0:
|
||||
break
|
||||
buffer=self._rreg(_APDS9960_GFIFO_U,min(128, 1 + (dataset_count * 4)))
|
||||
# Unpack data stream into more usable U/D/L/R datasets for analysis
|
||||
idx = 0
|
||||
for i in range(dataset_count):
|
||||
idx = i * 4
|
||||
buffer_dataset[0] = buffer[idx]
|
||||
buffer_dataset[1] = buffer[idx + 1]
|
||||
buffer_dataset[2] = buffer[idx + 2]
|
||||
buffer_dataset[3] = buffer[idx + 3]
|
||||
|
||||
if ((not all(val == 255 for val in buffer_dataset))
|
||||
and (not all(val == 0 for val in buffer_dataset))
|
||||
and (all(val >= 30 for val in buffer_dataset))
|
||||
):
|
||||
if len(frame) < 2:
|
||||
frame.append(tuple(buffer_dataset))
|
||||
else:
|
||||
frame[1] = tuple(buffer_dataset)
|
||||
time.sleep(0.03)
|
||||
if len(frame) < 2:
|
||||
return None
|
||||
# Determine our up/down and left/right ratios along with our first/last deltas
|
||||
f_r_ud = ((frame[0][0] - frame[0][1]) * 100) // (frame[0][0] + frame[0][1])
|
||||
f_r_lr = ((frame[0][2] - frame[0][3]) * 100) // (frame[0][2] + frame[0][3])
|
||||
l_r_ud = ((frame[1][0] - frame[1][1]) * 100) // (frame[1][0] + frame[1][1])
|
||||
l_r_lr = ((frame[1][2] - frame[1][3]) * 100) // (frame[1][2] + frame[1][3])
|
||||
delta_ud = l_r_ud - f_r_ud
|
||||
delta_lr = l_r_lr - f_r_lr
|
||||
# Make our first guess at what gesture we saw, if any
|
||||
state_ud = 0
|
||||
state_lr = 0
|
||||
if delta_ud >= 30:
|
||||
state_ud = 1
|
||||
elif delta_ud <= -30:
|
||||
state_ud = -1
|
||||
|
||||
if delta_lr >= 30:
|
||||
state_lr = 1
|
||||
elif delta_lr <= -30:
|
||||
state_lr = -1
|
||||
# Make our final decision based on our first guess and, if required, the delta data
|
||||
gesture_found = 0
|
||||
# Easy cases
|
||||
if state_ud == -1 and state_lr == 0:
|
||||
gesture_found = 1
|
||||
elif state_ud == 1 and state_lr == 0:
|
||||
gesture_found = 2
|
||||
elif state_ud == 0 and state_lr == -1:
|
||||
gesture_found = 3
|
||||
elif state_ud == 0 and state_lr == 1:
|
||||
gesture_found = 4
|
||||
# Not so easy cases
|
||||
if gesture_found == 0:
|
||||
if state_ud == -1 and state_lr == 1:
|
||||
if abs(delta_ud) > abs(delta_lr):
|
||||
gesture_found = 1
|
||||
else:
|
||||
gesture_found = 4
|
||||
elif state_ud == 1 and state_lr == -1:
|
||||
if abs(delta_ud) > abs(delta_lr):
|
||||
gesture_found = 2
|
||||
else:
|
||||
gesture_found = 3
|
||||
elif state_ud == -1 and state_lr == -1:
|
||||
if abs(delta_ud) > abs(delta_lr):
|
||||
gesture_found = 1
|
||||
else:
|
||||
gesture_found = 3
|
||||
elif state_ud == 1 and state_lr == 1:
|
||||
if abs(delta_ud) > abs(delta_lr):
|
||||
gesture_found = 2
|
||||
else:
|
||||
gesture_found = 3
|
||||
|
||||
dir_lookup = [None,"left", "right", "down", "up"]
|
||||
return dir_lookup[gesture_found]
|
||||
|
||||
## COLOR
|
||||
def color(self,gain=1):
|
||||
"""Tuple containing red, green, blue, and clear light intensity values"""
|
||||
if self._select[2]:
|
||||
self._select=[True,True,False]
|
||||
self.enable_proximity(False)
|
||||
self.enable_gesture(False)
|
||||
self.enable_color(True)
|
||||
self.color_gain(gain)
|
||||
|
||||
while not self._get_bit(_APDS9960_STATUS, _BIT_MASK_STATUS_AVALID):
|
||||
time.sleep(0.005) #"""Color data ready flag"""
|
||||
return (
|
||||
self._color_data16(_APDS9960_CDATAL + 2),
|
||||
self._color_data16(_APDS9960_CDATAL + 4),
|
||||
self._color_data16(_APDS9960_CDATAL + 6),
|
||||
self._color_data16(_APDS9960_CDATAL),
|
||||
)
|
||||
114
mixly/boards/default/micropython/build/lib/baidu_speech.py
Normal file
114
mixly/boards/default/micropython/build/lib/baidu_speech.py
Normal file
@@ -0,0 +1,114 @@
|
||||
"""
|
||||
Baidu ASR API
|
||||
|
||||
MicroPython library for Baidu ASR API
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20230223
|
||||
#https://ai.baidu.com/ai-doc/SPEECH/Ek39uxgre
|
||||
#https://ai.baidu.com/unit/home#/home
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import json,gc
|
||||
import urequests,array
|
||||
from ubinascii import hexlify
|
||||
from machine import Timer,unique_id
|
||||
|
||||
'''Set constant'''
|
||||
_framerate=8000
|
||||
_unique_id=hexlify(unique_id()).decode()
|
||||
|
||||
def urequests_api(method, url, **kw):
|
||||
'''Request data'''
|
||||
try:
|
||||
return json.loads(urequests.request(method, url, **kw).text)
|
||||
except Exception as e:
|
||||
raise RuntimeError("API request failed or WiFi is not connected",e)
|
||||
|
||||
def fetch_token(API_Key,Secret_Key):
|
||||
"""Get access_token"""
|
||||
url='http://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={}&client_secret={}'.format(API_Key,Secret_Key)
|
||||
results=urequests_api("GET",url)
|
||||
if "error_description" in results.keys():
|
||||
raise ValueError(results["error_description"])
|
||||
if "access_token" in results.keys():
|
||||
return results["access_token"]
|
||||
|
||||
class Recorder:
|
||||
def __init__(self, adc,timer=2):
|
||||
self._timer=Timer(timer)
|
||||
self._mic=adc
|
||||
|
||||
def _timer_callback(self,timer):
|
||||
'''Timer callback read microphone'''
|
||||
try:
|
||||
_mic=self._mic.read_u16()-32768
|
||||
self._pcm_buffer.append(_mic &0xFF)
|
||||
self._pcm_buffer.append(_mic >>8)
|
||||
self._record_time-=1
|
||||
except:
|
||||
print("Warning: MemoryError!")
|
||||
self._pcm_buffer=bytearray()
|
||||
gc.collect()
|
||||
self._record_time=0
|
||||
|
||||
def record(self,record_time=1):
|
||||
"""Call timer to record audio"""
|
||||
self._pcm_buffer=bytearray()
|
||||
gc.collect()
|
||||
self._record_time=record_time*_framerate
|
||||
self._timer.init(freq =_framerate, mode = Timer.PERIODIC, callback = self._timer_callback)
|
||||
while True:
|
||||
if self._record_time <= 0:
|
||||
self._timer.deinit()
|
||||
gc.collect()
|
||||
return self._pcm_buffer
|
||||
|
||||
class ASR(Recorder):
|
||||
def __init__(self, adc, API_Key, Secret_Key, timer=2):
|
||||
self._token=fetch_token(API_Key,Secret_Key)
|
||||
super().__init__(adc,timer)
|
||||
|
||||
def recognize(self,record_time=1,dev_pid=1537):
|
||||
"""Access API to get voice results"""
|
||||
pcm_buffer=self.record(record_time)
|
||||
if max(pcm_buffer)>=250:
|
||||
url='http://vop.baidu.com/server_api?dev_pid={}&cuid={}&token={}'.format(dev_pid,_unique_id,self._token)
|
||||
headers = {'Content-Type': 'audio/pcm; rate={}'.format(_framerate)}
|
||||
results=urequests_api("POST",url,data=pcm_buffer,headers=headers)
|
||||
if results["err_no"] != 0:
|
||||
raise ValueError(results["err_msg"],results["err_no"])
|
||||
elif results["err_msg"] == "success.":
|
||||
gc.collect()
|
||||
return results["result"][0]
|
||||
else:
|
||||
return ''
|
||||
|
||||
class UNIT:
|
||||
def __init__(self, API_Key, Secret_Key):
|
||||
self._token=fetch_token(API_Key,Secret_Key)
|
||||
self._session_id=""
|
||||
|
||||
def chatbot(self,chatbot_id,query):
|
||||
"""Access API to intelligent dialog"""
|
||||
if len(query) > 0:
|
||||
url='https://aip.baidubce.com/rpc/2.0/unit/service/v3/chat?access_token={}'.format(self._token)
|
||||
data={"log_id":"log"+_unique_id,
|
||||
"version":"3.0",
|
||||
"service_id":chatbot_id,
|
||||
"session_id":self._session_id,
|
||||
"request":{"query":query,"terminal_id":_unique_id}}
|
||||
headers = {"content-type": "application/json"}
|
||||
results=urequests_api("POST",url,data=json.dumps(data).encode(),headers=headers)
|
||||
if results["error_code"] != 0:
|
||||
raise ValueError(results["error_msg"],results["error_code"])
|
||||
elif results["error_msg"] == "success":
|
||||
self._session_id=results["result"]['session_id']
|
||||
gc.collect()
|
||||
return results["result"]['responses'][0]['actions'][0]['say']
|
||||
else:
|
||||
return ''
|
||||
|
||||
gc.collect()
|
||||
480
mixly/boards/default/micropython/build/lib/base64.py
Normal file
480
mixly/boards/default/micropython/build/lib/base64.py
Normal file
@@ -0,0 +1,480 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
"""RFC 3548: Base16, Base32, Base64 Data Encodings"""
|
||||
|
||||
# Modified 04-Oct-1995 by Jack Jansen to use binascii module
|
||||
# Modified 30-Dec-2003 by Barry Warsaw to add full RFC 3548 support
|
||||
# Modified 22-May-2007 by Guido van Rossum to use bytes everywhere
|
||||
|
||||
import re
|
||||
import struct
|
||||
import binascii
|
||||
|
||||
|
||||
__all__ = [
|
||||
# Legacy interface exports traditional RFC 1521 Base64 encodings
|
||||
"encode",
|
||||
"decode",
|
||||
"encodebytes",
|
||||
"decodebytes",
|
||||
# Generalized interface for other encodings
|
||||
"b64encode",
|
||||
"b64decode",
|
||||
"b32encode",
|
||||
"b32decode",
|
||||
"b16encode",
|
||||
"b16decode",
|
||||
# Standard Base64 encoding
|
||||
"standard_b64encode",
|
||||
"standard_b64decode",
|
||||
# Some common Base64 alternatives. As referenced by RFC 3458, see thread
|
||||
# starting at:
|
||||
#
|
||||
# http://zgp.org/pipermail/p2p-hackers/2001-September/000316.html
|
||||
"urlsafe_b64encode",
|
||||
"urlsafe_b64decode",
|
||||
]
|
||||
|
||||
|
||||
bytes_types = (bytes, bytearray) # Types acceptable as binary data
|
||||
|
||||
|
||||
def _bytes_from_decode_data(s):
|
||||
if isinstance(s, str):
|
||||
try:
|
||||
return s.encode("ascii")
|
||||
# except UnicodeEncodeError:
|
||||
except:
|
||||
raise ValueError("string argument should contain only ASCII characters")
|
||||
elif isinstance(s, bytes_types):
|
||||
return s
|
||||
else:
|
||||
raise TypeError("argument should be bytes or ASCII string, not %s" % s.__class__.__name__)
|
||||
|
||||
|
||||
def _maketrans(f, t):
|
||||
"""Re-implement bytes.maketrans() as there is no such function in micropython"""
|
||||
if len(f) != len(t):
|
||||
raise ValueError("maketrans arguments must have same length")
|
||||
translation_table = dict(zip(f, t))
|
||||
return translation_table
|
||||
|
||||
|
||||
def _translate(input_bytes, trans_table):
|
||||
"""Re-implement bytes.translate() as there is no such function in micropython"""
|
||||
result = bytearray()
|
||||
|
||||
for byte in input_bytes:
|
||||
translated_byte = trans_table.get(byte, byte)
|
||||
result.append(translated_byte)
|
||||
|
||||
return bytes(result)
|
||||
|
||||
|
||||
# Base64 encoding/decoding uses binascii
|
||||
|
||||
|
||||
def b64encode(s, altchars=None):
|
||||
"""Encode a byte string using Base64.
|
||||
|
||||
s is the byte string to encode. Optional altchars must be a byte
|
||||
string of length 2 which specifies an alternative alphabet for the
|
||||
'+' and '/' characters. This allows an application to
|
||||
e.g. generate url or filesystem safe Base64 strings.
|
||||
|
||||
The encoded byte string is returned.
|
||||
"""
|
||||
if not isinstance(s, bytes_types):
|
||||
raise TypeError("expected bytes, not %s" % s.__class__.__name__)
|
||||
# Strip off the trailing newline
|
||||
encoded = binascii.b2a_base64(s)[:-1]
|
||||
if altchars is not None:
|
||||
if not isinstance(altchars, bytes_types):
|
||||
raise TypeError("expected bytes, not %s" % altchars.__class__.__name__)
|
||||
assert len(altchars) == 2, repr(altchars)
|
||||
encoded = _translate(encoded, _maketrans(b"+/", altchars))
|
||||
return encoded
|
||||
|
||||
|
||||
def b64decode(s, altchars=None, validate=False):
|
||||
"""Decode a Base64 encoded byte string.
|
||||
|
||||
s is the byte string to decode. Optional altchars must be a
|
||||
string of length 2 which specifies the alternative alphabet used
|
||||
instead of the '+' and '/' characters.
|
||||
|
||||
The decoded string is returned. A binascii.Error is raised if s is
|
||||
incorrectly padded.
|
||||
|
||||
If validate is False (the default), non-base64-alphabet characters are
|
||||
discarded prior to the padding check. If validate is True,
|
||||
non-base64-alphabet characters in the input result in a binascii.Error.
|
||||
"""
|
||||
s = _bytes_from_decode_data(s)
|
||||
if altchars is not None:
|
||||
altchars = _bytes_from_decode_data(altchars)
|
||||
assert len(altchars) == 2, repr(altchars)
|
||||
s = _translate(s, _maketrans(altchars, b"+/"))
|
||||
if validate and not re.match(b"^[A-Za-z0-9+/]*=*$", s):
|
||||
raise binascii.Error("Non-base64 digit found")
|
||||
return binascii.a2b_base64(s)
|
||||
|
||||
|
||||
def standard_b64encode(s):
|
||||
"""Encode a byte string using the standard Base64 alphabet.
|
||||
|
||||
s is the byte string to encode. The encoded byte string is returned.
|
||||
"""
|
||||
return b64encode(s)
|
||||
|
||||
|
||||
def standard_b64decode(s):
|
||||
"""Decode a byte string encoded with the standard Base64 alphabet.
|
||||
|
||||
s is the byte string to decode. The decoded byte string is
|
||||
returned. binascii.Error is raised if the input is incorrectly
|
||||
padded or if there are non-alphabet characters present in the
|
||||
input.
|
||||
"""
|
||||
return b64decode(s)
|
||||
|
||||
|
||||
# _urlsafe_encode_translation = _maketrans(b'+/', b'-_')
|
||||
# _urlsafe_decode_translation = _maketrans(b'-_', b'+/')
|
||||
|
||||
|
||||
def urlsafe_b64encode(s):
|
||||
"""Encode a byte string using a url-safe Base64 alphabet.
|
||||
|
||||
s is the byte string to encode. The encoded byte string is
|
||||
returned. The alphabet uses '-' instead of '+' and '_' instead of
|
||||
'/'.
|
||||
"""
|
||||
# return b64encode(s).translate(_urlsafe_encode_translation)
|
||||
return b64encode(s, b"-_").rstrip(b"\n")
|
||||
|
||||
|
||||
def urlsafe_b64decode(s):
|
||||
"""Decode a byte string encoded with the standard Base64 alphabet.
|
||||
|
||||
s is the byte string to decode. The decoded byte string is
|
||||
returned. binascii.Error is raised if the input is incorrectly
|
||||
padded or if there are non-alphabet characters present in the
|
||||
input.
|
||||
|
||||
The alphabet uses '-' instead of '+' and '_' instead of '/'.
|
||||
"""
|
||||
# s = _bytes_from_decode_data(s)
|
||||
# s = s.translate(_urlsafe_decode_translation)
|
||||
# return b64decode(s)
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
# Base32 encoding/decoding must be done in Python
|
||||
_b32alphabet = {
|
||||
0: b"A",
|
||||
9: b"J",
|
||||
18: b"S",
|
||||
27: b"3",
|
||||
1: b"B",
|
||||
10: b"K",
|
||||
19: b"T",
|
||||
28: b"4",
|
||||
2: b"C",
|
||||
11: b"L",
|
||||
20: b"U",
|
||||
29: b"5",
|
||||
3: b"D",
|
||||
12: b"M",
|
||||
21: b"V",
|
||||
30: b"6",
|
||||
4: b"E",
|
||||
13: b"N",
|
||||
22: b"W",
|
||||
31: b"7",
|
||||
5: b"F",
|
||||
14: b"O",
|
||||
23: b"X",
|
||||
6: b"G",
|
||||
15: b"P",
|
||||
24: b"Y",
|
||||
7: b"H",
|
||||
16: b"Q",
|
||||
25: b"Z",
|
||||
8: b"I",
|
||||
17: b"R",
|
||||
26: b"2",
|
||||
}
|
||||
|
||||
_b32tab = [v[0] for k, v in sorted(_b32alphabet.items())]
|
||||
_b32rev = dict([(v[0], k) for k, v in _b32alphabet.items()])
|
||||
|
||||
|
||||
def b32encode(s):
|
||||
"""Encode a byte string using Base32.
|
||||
|
||||
s is the byte string to encode. The encoded byte string is returned.
|
||||
"""
|
||||
if not isinstance(s, bytes_types):
|
||||
raise TypeError("expected bytes, not %s" % s.__class__.__name__)
|
||||
quanta, leftover = divmod(len(s), 5)
|
||||
# Pad the last quantum with zero bits if necessary
|
||||
if leftover:
|
||||
s = s + bytes(5 - leftover) # Don't use += !
|
||||
quanta += 1
|
||||
encoded = bytearray()
|
||||
for i in range(quanta):
|
||||
# c1 and c2 are 16 bits wide, c3 is 8 bits wide. The intent of this
|
||||
# code is to process the 40 bits in units of 5 bits. So we take the 1
|
||||
# leftover bit of c1 and tack it onto c2. Then we take the 2 leftover
|
||||
# bits of c2 and tack them onto c3. The shifts and masks are intended
|
||||
# to give us values of exactly 5 bits in width.
|
||||
c1, c2, c3 = struct.unpack("!HHB", s[i * 5 : (i + 1) * 5])
|
||||
c2 += (c1 & 1) << 16 # 17 bits wide
|
||||
c3 += (c2 & 3) << 8 # 10 bits wide
|
||||
encoded += bytes(
|
||||
[
|
||||
_b32tab[c1 >> 11], # bits 1 - 5
|
||||
_b32tab[(c1 >> 6) & 0x1F], # bits 6 - 10
|
||||
_b32tab[(c1 >> 1) & 0x1F], # bits 11 - 15
|
||||
_b32tab[c2 >> 12], # bits 16 - 20 (1 - 5)
|
||||
_b32tab[(c2 >> 7) & 0x1F], # bits 21 - 25 (6 - 10)
|
||||
_b32tab[(c2 >> 2) & 0x1F], # bits 26 - 30 (11 - 15)
|
||||
_b32tab[c3 >> 5], # bits 31 - 35 (1 - 5)
|
||||
_b32tab[c3 & 0x1F], # bits 36 - 40 (1 - 5)
|
||||
]
|
||||
)
|
||||
# Adjust for any leftover partial quanta
|
||||
if leftover == 1:
|
||||
encoded = encoded[:-6] + b"======"
|
||||
elif leftover == 2:
|
||||
encoded = encoded[:-4] + b"===="
|
||||
elif leftover == 3:
|
||||
encoded = encoded[:-3] + b"==="
|
||||
elif leftover == 4:
|
||||
encoded = encoded[:-1] + b"="
|
||||
return bytes(encoded)
|
||||
|
||||
|
||||
def b32decode(s, casefold=False, map01=None):
|
||||
"""Decode a Base32 encoded byte string.
|
||||
|
||||
s is the byte string to decode. Optional casefold is a flag
|
||||
specifying whether a lowercase alphabet is acceptable as input.
|
||||
For security purposes, the default is False.
|
||||
|
||||
RFC 3548 allows for optional mapping of the digit 0 (zero) to the
|
||||
letter O (oh), and for optional mapping of the digit 1 (one) to
|
||||
either the letter I (eye) or letter L (el). The optional argument
|
||||
map01 when not None, specifies which letter the digit 1 should be
|
||||
mapped to (when map01 is not None, the digit 0 is always mapped to
|
||||
the letter O). For security purposes the default is None, so that
|
||||
0 and 1 are not allowed in the input.
|
||||
|
||||
The decoded byte string is returned. binascii.Error is raised if
|
||||
the input is incorrectly padded or if there are non-alphabet
|
||||
characters present in the input.
|
||||
"""
|
||||
s = _bytes_from_decode_data(s)
|
||||
quanta, leftover = divmod(len(s), 8)
|
||||
if leftover:
|
||||
raise binascii.Error("Incorrect padding")
|
||||
# Handle section 2.4 zero and one mapping. The flag map01 will be either
|
||||
# False, or the character to map the digit 1 (one) to. It should be
|
||||
# either L (el) or I (eye).
|
||||
if map01 is not None:
|
||||
map01 = _bytes_from_decode_data(map01)
|
||||
assert len(map01) == 1, repr(map01)
|
||||
s = _translate(s, _maketrans(b"01", b"O" + map01))
|
||||
if casefold:
|
||||
s = s.upper()
|
||||
# Strip off pad characters from the right. We need to count the pad
|
||||
# characters because this will tell us how many null bytes to remove from
|
||||
# the end of the decoded string.
|
||||
padchars = s.find(b"=")
|
||||
if padchars > 0:
|
||||
padchars = len(s) - padchars
|
||||
s = s[:-padchars]
|
||||
else:
|
||||
padchars = 0
|
||||
|
||||
# Now decode the full quanta
|
||||
parts = []
|
||||
acc = 0
|
||||
shift = 35
|
||||
for c in s:
|
||||
val = _b32rev.get(c)
|
||||
if val is None:
|
||||
raise binascii.Error("Non-base32 digit found")
|
||||
acc += _b32rev[c] << shift
|
||||
shift -= 5
|
||||
if shift < 0:
|
||||
parts.append(binascii.unhexlify(bytes("%010x" % acc, "ascii")))
|
||||
acc = 0
|
||||
shift = 35
|
||||
# Process the last, partial quanta
|
||||
last = binascii.unhexlify(bytes("%010x" % acc, "ascii"))
|
||||
if padchars == 0:
|
||||
last = b"" # No characters
|
||||
elif padchars == 1:
|
||||
last = last[:-1]
|
||||
elif padchars == 3:
|
||||
last = last[:-2]
|
||||
elif padchars == 4:
|
||||
last = last[:-3]
|
||||
elif padchars == 6:
|
||||
last = last[:-4]
|
||||
else:
|
||||
raise binascii.Error("Incorrect padding")
|
||||
parts.append(last)
|
||||
return b"".join(parts)
|
||||
|
||||
|
||||
# RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns
|
||||
# lowercase. The RFC also recommends against accepting input case
|
||||
# insensitively.
|
||||
def b16encode(s):
|
||||
"""Encode a byte string using Base16.
|
||||
|
||||
s is the byte string to encode. The encoded byte string is returned.
|
||||
"""
|
||||
if not isinstance(s, bytes_types):
|
||||
raise TypeError("expected bytes, not %s" % s.__class__.__name__)
|
||||
return binascii.hexlify(s).upper()
|
||||
|
||||
|
||||
def b16decode(s, casefold=False):
|
||||
"""Decode a Base16 encoded byte string.
|
||||
|
||||
s is the byte string to decode. Optional casefold is a flag
|
||||
specifying whether a lowercase alphabet is acceptable as input.
|
||||
For security purposes, the default is False.
|
||||
|
||||
The decoded byte string is returned. binascii.Error is raised if
|
||||
s were incorrectly padded or if there are non-alphabet characters
|
||||
present in the string.
|
||||
"""
|
||||
s = _bytes_from_decode_data(s)
|
||||
if casefold:
|
||||
s = s.upper()
|
||||
if re.search(b"[^0-9A-F]", s):
|
||||
raise binascii.Error("Non-base16 digit found")
|
||||
return binascii.unhexlify(s)
|
||||
|
||||
|
||||
# Legacy interface. This code could be cleaned up since I don't believe
|
||||
# binascii has any line length limitations. It just doesn't seem worth it
|
||||
# though. The files should be opened in binary mode.
|
||||
|
||||
MAXLINESIZE = 76 # Excluding the CRLF
|
||||
MAXBINSIZE = (MAXLINESIZE // 4) * 3
|
||||
|
||||
|
||||
def encode(input, output):
|
||||
"""Encode a file; input and output are binary files."""
|
||||
while True:
|
||||
s = input.read(MAXBINSIZE)
|
||||
if not s:
|
||||
break
|
||||
while len(s) < MAXBINSIZE:
|
||||
ns = input.read(MAXBINSIZE - len(s))
|
||||
if not ns:
|
||||
break
|
||||
s += ns
|
||||
line = binascii.b2a_base64(s)
|
||||
output.write(line)
|
||||
|
||||
|
||||
def decode(input, output):
|
||||
"""Decode a file; input and output are binary files."""
|
||||
while True:
|
||||
line = input.readline()
|
||||
if not line:
|
||||
break
|
||||
s = binascii.a2b_base64(line)
|
||||
output.write(s)
|
||||
|
||||
|
||||
def encodebytes(s):
|
||||
"""Encode a bytestring into a bytestring containing multiple lines
|
||||
of base-64 data."""
|
||||
if not isinstance(s, bytes_types):
|
||||
raise TypeError("expected bytes, not %s" % s.__class__.__name__)
|
||||
pieces = []
|
||||
for i in range(0, len(s), MAXBINSIZE):
|
||||
chunk = s[i : i + MAXBINSIZE]
|
||||
pieces.append(binascii.b2a_base64(chunk))
|
||||
return b"".join(pieces)
|
||||
|
||||
|
||||
def encodestring(s):
|
||||
"""Legacy alias of encodebytes()."""
|
||||
import warnings
|
||||
|
||||
warnings.warn("encodestring() is a deprecated alias, use encodebytes()", DeprecationWarning, 2)
|
||||
return encodebytes(s)
|
||||
|
||||
|
||||
def decodebytes(s):
|
||||
"""Decode a bytestring of base-64 data into a bytestring."""
|
||||
if not isinstance(s, bytes_types):
|
||||
raise TypeError("expected bytes, not %s" % s.__class__.__name__)
|
||||
return binascii.a2b_base64(s)
|
||||
|
||||
|
||||
def decodestring(s):
|
||||
"""Legacy alias of decodebytes()."""
|
||||
import warnings
|
||||
|
||||
warnings.warn("decodestring() is a deprecated alias, use decodebytes()", DeprecationWarning, 2)
|
||||
return decodebytes(s)
|
||||
|
||||
|
||||
# Usable as a script...
|
||||
def main():
|
||||
"""Small main program"""
|
||||
import sys, getopt
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "deut")
|
||||
except getopt.error as msg:
|
||||
sys.stdout = sys.stderr
|
||||
print(msg)
|
||||
print(
|
||||
"""usage: %s [-d|-e|-u|-t] [file|-]
|
||||
-d, -u: decode
|
||||
-e: encode (default)
|
||||
-t: encode and decode string 'Aladdin:open sesame'"""
|
||||
% sys.argv[0]
|
||||
)
|
||||
sys.exit(2)
|
||||
func = encode
|
||||
for o, a in opts:
|
||||
if o == "-e":
|
||||
func = encode
|
||||
if o == "-d":
|
||||
func = decode
|
||||
if o == "-u":
|
||||
func = decode
|
||||
if o == "-t":
|
||||
test()
|
||||
return
|
||||
if args and args[0] != "-":
|
||||
with open(args[0], "rb") as f:
|
||||
func(f, sys.stdout.buffer)
|
||||
else:
|
||||
func(sys.stdin.buffer, sys.stdout.buffer)
|
||||
|
||||
|
||||
def test():
|
||||
s0 = b"Aladdin:open sesame"
|
||||
print(repr(s0))
|
||||
s1 = encodebytes(s0)
|
||||
print(repr(s1))
|
||||
s2 = decodebytes(s1)
|
||||
print(repr(s2))
|
||||
assert s0 == s2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,79 @@
|
||||
# Helpers for generating BLE advertising payloads.
|
||||
|
||||
from micropython import const
|
||||
import struct
|
||||
import bluetooth
|
||||
|
||||
# Advertising payloads are repeated packets of the following form:
|
||||
# 1 byte data length (N + 1)
|
||||
# 1 byte type (see constants below)
|
||||
# N bytes type-specific data
|
||||
|
||||
_ADV_TYPE_FLAGS = const(0x01)
|
||||
_ADV_TYPE_NAME = const(0x09)
|
||||
_ADV_TYPE_UUID16_COMPLETE = const(0x3)
|
||||
_ADV_TYPE_UUID32_COMPLETE = const(0x5)
|
||||
_ADV_TYPE_UUID128_COMPLETE = const(0x7)
|
||||
_ADV_TYPE_UUID16_MORE = const(0x2)
|
||||
_ADV_TYPE_UUID32_MORE = const(0x4)
|
||||
_ADV_TYPE_UUID128_MORE = const(0x6)
|
||||
_ADV_TYPE_APPEARANCE = const(0x19)
|
||||
|
||||
|
||||
# Generate a payload to be passed to gap_advertise(adv_data=...).
|
||||
def advertising_payload(limited_disc=False, br_edr=False, name=None, services=None, appearance=0):
|
||||
payload = bytearray()
|
||||
|
||||
def _append(adv_type, value):
|
||||
nonlocal payload
|
||||
payload += struct.pack("BB", len(value) + 1, adv_type) + value
|
||||
|
||||
_append(
|
||||
_ADV_TYPE_FLAGS,
|
||||
struct.pack("B", (0x01 if limited_disc else 0x02) + (0x18 if br_edr else 0x04)),
|
||||
)
|
||||
|
||||
if name:
|
||||
_append(_ADV_TYPE_NAME, name.encode())
|
||||
|
||||
if services:
|
||||
for uuid in services:
|
||||
b = bytes(uuid)
|
||||
if len(b) == 2:
|
||||
_append(_ADV_TYPE_UUID16_COMPLETE, b)
|
||||
elif len(b) == 4:
|
||||
_append(_ADV_TYPE_UUID32_COMPLETE, b)
|
||||
elif len(b) == 16:
|
||||
_append(_ADV_TYPE_UUID128_COMPLETE, b)
|
||||
|
||||
# See org.bluetooth.characteristic.gap.appearance.xml
|
||||
if appearance:
|
||||
_append(_ADV_TYPE_APPEARANCE, struct.pack("<h", appearance))
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
def decode_field(payload, adv_type):
|
||||
i = 0
|
||||
result = []
|
||||
while i + 1 < len(payload):
|
||||
if payload[i + 1] == adv_type:
|
||||
result.append(payload[i + 2 : i + payload[i] + 1])
|
||||
i += 1 + payload[i]
|
||||
return result
|
||||
|
||||
|
||||
def decode_name(payload):
|
||||
n = decode_field(payload, _ADV_TYPE_NAME)
|
||||
return str(n[0], "utf-8") if n else ""
|
||||
|
||||
|
||||
def decode_services(payload):
|
||||
services = []
|
||||
for u in decode_field(payload, _ADV_TYPE_UUID16_COMPLETE):
|
||||
services.append(bluetooth.UUID(struct.unpack("<h", u)[0]))
|
||||
for u in decode_field(payload, _ADV_TYPE_UUID32_COMPLETE):
|
||||
services.append(bluetooth.UUID(struct.unpack("<d", u)[0]))
|
||||
for u in decode_field(payload, _ADV_TYPE_UUID128_COMPLETE):
|
||||
services.append(bluetooth.UUID(u))
|
||||
return services
|
||||
217
mixly/boards/default/micropython/build/lib/ble_central.py
Normal file
217
mixly/boards/default/micropython/build/lib/ble_central.py
Normal file
@@ -0,0 +1,217 @@
|
||||
"""
|
||||
Bluetooth-Central
|
||||
|
||||
Micropython library for the Bluetooth-Central
|
||||
=======================================================
|
||||
#Preliminary composition 20221018
|
||||
#https://github.com/micropython/micropython/tree/master/examples/bluetooth
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time,gc
|
||||
import bluetooth
|
||||
from micropython import const
|
||||
from ubinascii import hexlify,unhexlify
|
||||
from ble_advertising import decode_services, decode_name
|
||||
|
||||
_IRQ_CENTRAL_CONNECT = const(1)
|
||||
_IRQ_CENTRAL_DISCONNECT = const(2)
|
||||
_IRQ_GATTS_WRITE = const(3)
|
||||
_IRQ_GATTS_READ_REQUEST = const(4)
|
||||
_IRQ_SCAN_RESULT = const(5)
|
||||
_IRQ_SCAN_DONE = const(6)
|
||||
_IRQ_PERIPHERAL_CONNECT = const(7)
|
||||
_IRQ_PERIPHERAL_DISCONNECT = const(8)
|
||||
_IRQ_GATTC_SERVICE_RESULT = const(9)
|
||||
_IRQ_GATTC_SERVICE_DONE = const(10)
|
||||
_IRQ_GATTC_CHARACTERISTIC_RESULT = const(11)
|
||||
_IRQ_GATTC_CHARACTERISTIC_DONE = const(12)
|
||||
_IRQ_GATTC_DESCRIPTOR_RESULT = const(13)
|
||||
_IRQ_GATTC_DESCRIPTOR_DONE = const(14)
|
||||
_IRQ_GATTC_READ_RESULT = const(15)
|
||||
_IRQ_GATTC_READ_DONE = const(16)
|
||||
_IRQ_GATTC_WRITE_DONE = const(17)
|
||||
_IRQ_GATTC_NOTIFY = const(18)
|
||||
_IRQ_GATTC_INDICATE = const(19)
|
||||
|
||||
_ADV_IND = const(0x00)
|
||||
_ADV_DIRECT_IND = const(0x01)
|
||||
_ADV_SCAN_IND = const(0x02)
|
||||
_ADV_NONCONN_IND = const(0x03)
|
||||
|
||||
_UART_SERVICE_UUID = bluetooth.UUID(0x1101)
|
||||
_UART_RX_CHAR_UUID = bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E")
|
||||
_UART_TX_CHAR_UUID = bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E")
|
||||
|
||||
|
||||
class BLESimpleCentral:
|
||||
def __init__(self):
|
||||
self._ble = bluetooth.BLE()
|
||||
self._scan_flg = True
|
||||
self._ble.active(True)
|
||||
self._ble.irq(self._irq)
|
||||
self._reset()
|
||||
self.scan()
|
||||
|
||||
def _reset(self):
|
||||
# Cached name and address from a successful scan.
|
||||
self._name = None
|
||||
self._addr_type = None
|
||||
self._addr = None
|
||||
|
||||
# Callbacks for completion of various operations.
|
||||
# These reset back to None after being invoked.
|
||||
self._conn_callback = None
|
||||
self._read_callback = None
|
||||
|
||||
# Persistent callback for when new data is notified from the device.
|
||||
self._notify_callback = None
|
||||
self._write_data=None
|
||||
|
||||
# Connected device.
|
||||
self._conn_handle = None
|
||||
self._start_handle = None
|
||||
self._end_handle = None
|
||||
self._tx_handle = None
|
||||
self._rx_handle = None
|
||||
|
||||
def _irq(self, event, data):
|
||||
if event == _IRQ_SCAN_RESULT:
|
||||
addr_type, addr, adv_type, rssi, adv_data = data
|
||||
|
||||
if adv_type in (_ADV_IND, _ADV_DIRECT_IND) and _UART_SERVICE_UUID in decode_services(adv_data):
|
||||
# Found a potential device, remember it and stop scanning.
|
||||
self._addr_type = addr_type
|
||||
self._addr = bytes(addr) # Note: addr buffer is owned by caller so need to copy it.
|
||||
self._name = decode_name(adv_data) or "?"
|
||||
if self._addr in self._info[2]:
|
||||
self._ble.gap_scan(None)
|
||||
else:
|
||||
self._info[0].append(self._name)
|
||||
self._info[1].append(self._addr_type)
|
||||
self._info[2].append(self._addr)
|
||||
self._info[3].append(rssi)
|
||||
|
||||
elif event == _IRQ_SCAN_DONE:
|
||||
self._scan_flg = False
|
||||
|
||||
elif event == _IRQ_PERIPHERAL_CONNECT:
|
||||
# Connect successful.
|
||||
conn_handle, addr_type, addr = data
|
||||
if addr_type == self._addr_type and addr == self._addr:
|
||||
self._conn_handle = conn_handle
|
||||
self._ble.gattc_discover_services(self._conn_handle)
|
||||
|
||||
elif event == _IRQ_PERIPHERAL_DISCONNECT:
|
||||
# Disconnect (either initiated by us or the remote end).
|
||||
conn_handle, _, _ = data
|
||||
if conn_handle == self._conn_handle:
|
||||
# If it was initiated by us, it'll already be reset.
|
||||
self._reset()
|
||||
|
||||
elif event == _IRQ_GATTC_SERVICE_RESULT:
|
||||
# Connected device returned a service.
|
||||
conn_handle, start_handle, end_handle, uuid = data
|
||||
print("service", data)
|
||||
if conn_handle == self._conn_handle and uuid == _UART_SERVICE_UUID:
|
||||
self._start_handle, self._end_handle = start_handle, end_handle
|
||||
|
||||
elif event == _IRQ_GATTC_SERVICE_DONE:
|
||||
# Service query complete.
|
||||
if self._start_handle and self._end_handle:
|
||||
self._ble.gattc_discover_characteristics(
|
||||
self._conn_handle, self._start_handle, self._end_handle
|
||||
)
|
||||
else:
|
||||
print("Failed to find uart service.")
|
||||
|
||||
elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT:
|
||||
# Connected device returned a characteristic.
|
||||
conn_handle, def_handle, value_handle, properties, uuid = data
|
||||
if conn_handle == self._conn_handle and uuid == _UART_RX_CHAR_UUID:
|
||||
self._rx_handle = value_handle
|
||||
if conn_handle == self._conn_handle and uuid == _UART_TX_CHAR_UUID:
|
||||
self._tx_handle = value_handle
|
||||
|
||||
elif event == _IRQ_GATTC_CHARACTERISTIC_DONE:
|
||||
# Characteristic query complete.
|
||||
if self._tx_handle is not None and self._rx_handle is not None:
|
||||
# We've finished connecting and discovering device, fire the connect callback.
|
||||
if self._conn_callback:
|
||||
self._conn_callback()
|
||||
else:
|
||||
print("Failed to find uart rx characteristic.")
|
||||
|
||||
elif event == _IRQ_GATTC_WRITE_DONE:
|
||||
conn_handle, value_handle, status = data
|
||||
print("TX complete")
|
||||
|
||||
elif event == _IRQ_GATTC_NOTIFY:
|
||||
conn_handle, value_handle, notify_data = data
|
||||
if conn_handle == self._conn_handle and value_handle == self._tx_handle:
|
||||
try:
|
||||
self._write_data=bytes(notify_data).decode().strip()
|
||||
except:
|
||||
self._write_data=bytes(notify_data)
|
||||
if self._notify_callback:
|
||||
self._notify_callback(self._write_data)
|
||||
|
||||
# Returns true if we've successfully connected and discovered characteristics.
|
||||
def is_connected(self):
|
||||
return (self._conn_handle is not None and self._tx_handle is not None and self._rx_handle is not None)
|
||||
|
||||
# Find a device advertising the environmental sensor service.
|
||||
def scan(self):
|
||||
self._info = [[],[],[],[]]
|
||||
self._ble.gap_scan(10000, 30000, 30000)
|
||||
while self._scan_flg:
|
||||
time.sleep_ms(10)
|
||||
self._scan_flg = True
|
||||
info=[]
|
||||
for i in range(len(self._info[0])):
|
||||
info.append([self._info[0][i],self._info[1][i],hexlify(self._info[2][i]).decode(),self._info[3][i]])
|
||||
return info
|
||||
|
||||
# Connect to the specified device (otherwise use cached address from a scan).
|
||||
def connect(self, name=None,mac=None, callback=None):
|
||||
if mac and unhexlify(mac) in self._info[2]:
|
||||
index=self._info[2].index(unhexlify(mac))
|
||||
self._addr_type=self._info[1][index]
|
||||
self._addr=unhexlify(mac)
|
||||
elif name and name in self._info[0]:
|
||||
index=self._info[0].index(name)
|
||||
self._addr_type=self._info[1][index]
|
||||
self._addr=self._info[2][index]
|
||||
else:
|
||||
raise ValueError("The '{}' Bluetooth was not found, Please check device is working".format(mac if name is None else name))
|
||||
self._conn_callback = callback
|
||||
self._ble.gap_connect(self._addr_type, self._addr)
|
||||
return True
|
||||
|
||||
# Disconnect from current device.
|
||||
def disconnect(self):
|
||||
if not self._conn_handle:
|
||||
return
|
||||
self._ble.gap_disconnect(self._conn_handle)
|
||||
self._reset()
|
||||
gc.collect()
|
||||
|
||||
# Send data over the UART
|
||||
def send(self, v, response=False):
|
||||
if not self.is_connected():
|
||||
return
|
||||
self._ble.gattc_write(self._conn_handle, self._rx_handle, v, 1 if response else 0)
|
||||
|
||||
# Set handler for when data is received over the UART.
|
||||
def recv(self, callback= None):
|
||||
if callback:
|
||||
self._notify_callback = callback
|
||||
else:
|
||||
write_data=self._write_data
|
||||
self._write_data=None
|
||||
return write_data
|
||||
|
||||
@property
|
||||
def mac(self):
|
||||
'''Get mac address'''
|
||||
return hexlify(self._ble.config('mac')[1]).decode()
|
||||
37
mixly/boards/default/micropython/build/lib/ble_handle.py
Normal file
37
mixly/boards/default/micropython/build/lib/ble_handle.py
Normal file
@@ -0,0 +1,37 @@
|
||||
"""
|
||||
Bluetooth remote control handle
|
||||
|
||||
Micropython library for the Bluetooth remote control handle
|
||||
=======================================================
|
||||
#Preliminary composition 202200704
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
from ble_peripheral import BLESimplePeripheral
|
||||
|
||||
class Handle(BLESimplePeripheral):
|
||||
def __init__(self):
|
||||
super().__init__(name="TUDAO_MASTER")
|
||||
self._buffer=bytearray(14)
|
||||
|
||||
def _receive_cb(self, data):
|
||||
if self._on_receive:
|
||||
if data !=self._buffer:
|
||||
self._buffer=data
|
||||
key=self._deal(self._buffer)
|
||||
self._on_receive(key[0],key[1],key[2],key[3])
|
||||
|
||||
def recv(self,callback):
|
||||
self._on_receive = callback
|
||||
if callback:
|
||||
super().recv(self._receive_cb)
|
||||
|
||||
def _u2s(self,n):
|
||||
return n if n < (1 << 7) else n - (1 << 8)
|
||||
|
||||
def _deal(self,data):
|
||||
if data[0]== 0xff and data[1]== 0xfe and data[12]== 0xfd and data[13]== 0xfc:
|
||||
return self._u2s(data[5]),self._u2s(data[6]),self._u2s(data[7]),self._u2s(data[8])
|
||||
else:
|
||||
return None,None,None,None
|
||||
235
mixly/boards/default/micropython/build/lib/ble_hid.py
Normal file
235
mixly/boards/default/micropython/build/lib/ble_hid.py
Normal file
@@ -0,0 +1,235 @@
|
||||
"""
|
||||
Bluetooth-HID
|
||||
|
||||
Micropython library for the Bluetooth-HID(Compliant with equipment)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import bluetooth
|
||||
import struct, time
|
||||
from micropython import const
|
||||
from ubinascii import hexlify
|
||||
from ble_advertising import advertising_payload
|
||||
from bluetooth import UUID, FLAG_READ, FLAG_WRITE ,FLAG_NOTIFY, FLAG_WRITE_NO_RESPONSE
|
||||
|
||||
_IRQ_CENTRAL_CONNECT = const(1)
|
||||
_IRQ_CENTRAL_DISCONNECT = const(2)
|
||||
_IRQ_GATTS_WRITE = const(3)
|
||||
_IRQ_MTU_EXCHANGED = const(21)
|
||||
_IRQ_CONNECTION_UPDATE = const(27)
|
||||
_IRQ_GET_SECRET = const(29)
|
||||
_IRQ_SET_SECRET = const(30)
|
||||
_IRQ_PASSKEY_ACTION = const(31)
|
||||
_PASSKEY_ACTION_INPUT = const(2)
|
||||
_PASSKEY_ACTION_DISP = const(3)
|
||||
_PASSKEY_ACTION_NUMCMP = const(4)
|
||||
|
||||
#HID 鼠标、键盘、手柄设备报告描述符
|
||||
_HID_INPUT_REPORT = const(b'\x05\x01\t\x02\xa1\x01\x85\x01\t\x01\xa1\x00\x05\t\x19\x01)\x03\x15\x00%\x01\x95\x03u\x01\x81\x02\x95\x01u\x05\x81\x03\x05\x01\t0\t1\t8\x15\x81%\x7fu\x08\x95\x03\x81\x06\xc0\xc0\x05\x01\t\x06\xa1\x01\x85\x02u\x01\x95\x08\x05\x07\x19\xe0)\xe7\x15\x00%\x01\x81\x02\x95\x01u\x08\x81\x01\x95\x05u\x01\x05\x08\x19\x01)\x05\x91\x02\x95\x01u\x03\x91\x01\x95\x06u\x08\x15\x00%e\x05\x07\x19\x00)e\x81\x00\xc0\x05\x01\t\x04\xa1\x01\x85\x03\xa1\x00\t0\t1\x15\x81%\x7fu\x08\x95\x02\x81\x02\x05\t)\x08\x19\x01\x95\x08u\x01%\x01\x15\x00\x81\x02\xc0\xc0')
|
||||
_KEYCODE = const(b'\x00\x00\x00\x00\x00\x00\x00\x00*+(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x00,\x9e\xb4\xa0\xa1\xa2\xa44\xa6\xa7\xa5\xae6-78\'\x1e\x1f !"#$%&\xb33\xb6.\xb7\xb8\x9f\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d/10\xa3\xad5\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\xaf\xb1\xb0\xb5L')
|
||||
|
||||
_DIS = (UUID(0x180A), ( (UUID(0x2A24), FLAG_READ),
|
||||
(UUID(0x2A25), FLAG_READ),
|
||||
(UUID(0x2A26), FLAG_READ),
|
||||
(UUID(0x2A27), FLAG_READ),
|
||||
(UUID(0x2A28), FLAG_READ),
|
||||
(UUID(0x2A29), FLAG_READ),
|
||||
(UUID(0x2A50), FLAG_READ), ), )
|
||||
|
||||
_BAS = (UUID(0x180F), ( (UUID(0x2A19), FLAG_READ | FLAG_NOTIFY, ((UUID(0x2902), 0x03), (UUID(0x2904), 0x01),)), ), )
|
||||
|
||||
_HIDS = (UUID(0x1812), ((UUID(0x2A4A), FLAG_READ),
|
||||
(UUID(0x2A4B), FLAG_READ),
|
||||
(UUID(0x2A4C), FLAG_READ | FLAG_WRITE | FLAG_WRITE_NO_RESPONSE),
|
||||
(UUID(0x2A4D), FLAG_READ | FLAG_NOTIFY, ((UUID(0x2902), 0x03), (UUID(0x2908), 0x03),)), #鼠标
|
||||
(UUID(0x2A4D), FLAG_READ | FLAG_NOTIFY, ((UUID(0x2902), 0x03), (UUID(0x2908), 0x03),)), #键盘发送
|
||||
(UUID(0x2A4D), FLAG_READ | FLAG_WRITE, ((UUID(0x2902), 0x03), (UUID(0x2908), 0x03),)), #键盘状态
|
||||
(UUID(0x2A4D), FLAG_READ | FLAG_NOTIFY, ((UUID(0x2902), 0x03), (UUID(0x2908), 0x03),)), #游戏手柄
|
||||
(UUID(0x2A4E), FLAG_READ | FLAG_WRITE | FLAG_WRITE_NO_RESPONSE), ), )
|
||||
|
||||
class HID:
|
||||
def __init__(self, name=None, passkey=1234, battery_level=100):
|
||||
if (name is '') or (name is None):
|
||||
name = "Mixgo_" + self.mac[-6:].upper()
|
||||
print("HID Name:", name)
|
||||
|
||||
self._ble = bluetooth.BLE()
|
||||
self._ble.active(True)
|
||||
self._ble.irq(self._irq)
|
||||
self._ble.config(gap_name=name)
|
||||
self._ble.config(mtu=23)
|
||||
self.device_state = False
|
||||
self.conn_handle = None
|
||||
self.passkey = passkey
|
||||
self.battery_level = battery_level
|
||||
self.report = b'\x00'
|
||||
try:
|
||||
import ble_hid_key
|
||||
self.keys = ble_hid_key.keys
|
||||
except:
|
||||
self.keys = {}
|
||||
|
||||
handles = self._ble.gatts_register_services((_DIS, _BAS, _HIDS))
|
||||
self._service_characteristics(handles)
|
||||
self._payload = advertising_payload(name=name, services=[UUID(0x1812)], appearance=const(960))
|
||||
self.advertise()
|
||||
|
||||
def _irq(self, event, data):
|
||||
# Interrupt request callback function
|
||||
if event == _IRQ_CENTRAL_CONNECT:
|
||||
self.conn_handle, _, _ = data
|
||||
print("HID connected:", self.conn_handle)
|
||||
self.device_state = True
|
||||
elif event == _IRQ_CENTRAL_DISCONNECT:
|
||||
self.conn_handle = None
|
||||
conn_handle, addr_type, addr = data
|
||||
print("HID disconnected:", conn_handle)
|
||||
self.advertise()
|
||||
self.device_state = False
|
||||
elif event == _IRQ_MTU_EXCHANGED:
|
||||
conn_handle, mtu = data
|
||||
self._ble.config(mtu=mtu)
|
||||
print("MTU exchanged:", mtu)
|
||||
elif event == _IRQ_CONNECTION_UPDATE:
|
||||
self.conn_handle, _, _, _, _ = data
|
||||
print("Connection update")
|
||||
elif event == _IRQ_PASSKEY_ACTION:
|
||||
conn_handle, action, passkey = data
|
||||
print("Passkey action", conn_handle, action, passkey)
|
||||
if action == _PASSKEY_ACTION_NUMCMP:
|
||||
self._ble.gap_passkey(conn_handle, action, False)
|
||||
elif action == _PASSKEY_ACTION_DISP:
|
||||
print("Displaying passkey")
|
||||
self._ble.gap_passkey(conn_handle, action, self.passkey)
|
||||
elif action == _PASSKEY_ACTION_INPUT:
|
||||
print("Prompting for passkey")
|
||||
self._ble.gap_passkey(conn_handle, action, None)
|
||||
else:
|
||||
print("Unknown action")
|
||||
elif event == _IRQ_GATTS_WRITE:
|
||||
conn_handle, attr_handle = data
|
||||
self.report = self._ble.gatts_read(attr_handle)
|
||||
elif event == _IRQ_SET_SECRET:
|
||||
sec_type, key, value = data
|
||||
key = sec_type, bytes(key)
|
||||
value = bytes(value) if value else None
|
||||
#print("Set secret: ", key, value)
|
||||
if value is None:
|
||||
if key in self.keys:
|
||||
del self.keys[key]
|
||||
self._key_secrets(self.keys)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
self.keys[key] = value
|
||||
self._key_secrets(self.keys)
|
||||
return True
|
||||
elif event == _IRQ_GET_SECRET:
|
||||
sec_type, index, key = data
|
||||
#print("Get secret: ", sec_type, index, bytes(key) if key else None)
|
||||
if key is None:
|
||||
i = 0
|
||||
for (t, _key), value in self.keys.items():
|
||||
if t == sec_type:
|
||||
if i == index:
|
||||
return value
|
||||
i += 1
|
||||
return None
|
||||
else:
|
||||
key = sec_type, bytes(key)
|
||||
return self.keys.get(key, None)
|
||||
# else:
|
||||
# print("Unhandled IRQ event: ", event, data)
|
||||
|
||||
def _key_secrets(self, keys={}):
|
||||
"""Save pairing key"""
|
||||
with open("ble_hid_key.py", "w+") as s_f:
|
||||
s_f.write("keys=" + str(keys) + "\n")
|
||||
|
||||
def _service_characteristics(self, handles):
|
||||
"""Write BAS&service characteristics."""
|
||||
(h_mod, h_ser, h_fwr, h_hwr, h_swr, h_man, h_pnp) = handles[0]
|
||||
(self.h_bat, h_ccc, h_bfmt) = handles[1]
|
||||
(h_info, h_hid, _, self.m_rep, _, h_d1, self.k_rep, _, h_d2, _, _, h_d3, self.j_rep, _, h_d4, h_proto) = handles[2]
|
||||
# Write DIS characteristics.
|
||||
self._ble.gatts_write(h_mod, b'1')
|
||||
self._ble.gatts_write(h_ser, b'1')
|
||||
self._ble.gatts_write(h_fwr, b'1')
|
||||
self._ble.gatts_write(h_hwr, b'1')
|
||||
self._ble.gatts_write(h_swr, b'1')
|
||||
self._ble.gatts_write(h_man, b'Homebrew')
|
||||
self._ble.gatts_write(h_pnp, b'\x01a\xfe\x01\x00#\x01')
|
||||
# Write BAS characteristics.
|
||||
self._ble.gatts_write(self.h_bat, struct.pack("<B", self.battery_level))
|
||||
self._ble.gatts_write(h_bfmt, b'\x04\x00\xad\x27\x01\x00\x00')
|
||||
self._ble.gatts_write(h_ccc, b'\x00\x00')
|
||||
# Write service characteristics
|
||||
self._ble.gatts_write(h_info, b"\x01\x01\x00\x02")
|
||||
self._ble.gatts_write(h_hid, _HID_INPUT_REPORT)
|
||||
self._ble.gatts_write(h_d1, b'\x01\x01')
|
||||
self._ble.gatts_write(h_d2, b'\x02\x01')
|
||||
self._ble.gatts_write(h_d3, b'\x02\x02')
|
||||
self._ble.gatts_write(h_d4, b'\x03\x01')
|
||||
self._ble.gatts_write(h_proto, b"\x01")
|
||||
|
||||
def is_connected(self):
|
||||
'''蓝牙是否连接成功'''
|
||||
return self.device_state
|
||||
|
||||
def advertise(self, interval_us=100000):
|
||||
'''蓝牙广播'''
|
||||
print("Starting advertising")
|
||||
self._ble.gap_advertise(interval_us, adv_data=self._payload)
|
||||
|
||||
def battery_notify(self, level):
|
||||
'''电池电量%'''
|
||||
if self.is_connected():
|
||||
self.battery_level = max(min(level, 100), 0)
|
||||
self._ble.gatts_notify(self.conn_handle, self.h_bat, struct.pack("<B", self.battery_level))
|
||||
|
||||
def keyboard_state(self):
|
||||
'''获取键盘 指示灯状态'''
|
||||
return int.from_bytes(self.report, 'big')
|
||||
|
||||
def keyboard_notify(self, special=0, general=0, release=True):
|
||||
'''键盘 特殊按键 + 常规组合按键*6'''
|
||||
if self.is_connected():
|
||||
_keys = bytearray(6)
|
||||
if type(general) in (tuple, list):
|
||||
for i in range(len(general)):
|
||||
if i > 5: break
|
||||
_keys[i] = general[i]
|
||||
else:
|
||||
_keys[0] = general
|
||||
self._ble.gatts_notify(self.conn_handle, self.k_rep, bytes([special & 0xFF, 0]) + _keys)
|
||||
if release:
|
||||
time.sleep_ms(10)
|
||||
self._ble.gatts_notify(self.conn_handle, self.k_rep, b'\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||
|
||||
def keyboard_str(self, string, delay=0):
|
||||
'''键盘发送ASCLL码'''
|
||||
for char in str(string):
|
||||
char = max(min(ord(char), 127), 0)
|
||||
self.keyboard_notify( 0x02 if _KEYCODE[char] >> 7 else 0x00, _KEYCODE[char] & 0x7F)
|
||||
time.sleep_ms(20 + delay)
|
||||
|
||||
def mouse_notify(self, keys=0, move=(0, 0), wheel=0, release=True):
|
||||
'''鼠标 按键*3 + 位移 + 滚轮'''
|
||||
if self.is_connected():
|
||||
self._ble.gatts_notify(self.conn_handle, self.m_rep, bytes([keys & 0x0F, move[0] & 0xFF, move[1] & 0xFF, wheel & 0xFF]))
|
||||
if release:
|
||||
time.sleep_ms(10)
|
||||
self._ble.gatts_notify(self.conn_handle, self.m_rep, b'\x00\x00\x00\x00')
|
||||
|
||||
def Joystick_notify(self, keys=0, axes=(0, 0), release=False):
|
||||
'''手柄 按键*8 + 摇杆'''
|
||||
if self.is_connected():
|
||||
self._ble.gatts_notify(self.conn_handle, self.j_rep, bytes([axes[0] & 0xFF, axes[1] & 0xFF, keys & 0xFF]))
|
||||
if release:
|
||||
time.sleep_ms(10)
|
||||
self._ble.gatts_notify(self.conn_handle, self.j_rep, b'\x00\x00\x00')
|
||||
@property
|
||||
def mac(self):
|
||||
'''Get mac address'''
|
||||
return hexlify(self._ble.config('mac')[1]).decode()
|
||||
218
mixly/boards/default/micropython/build/lib/ble_hid_keyboard.py
Normal file
218
mixly/boards/default/micropython/build/lib/ble_hid_keyboard.py
Normal file
@@ -0,0 +1,218 @@
|
||||
"""
|
||||
Bluetooth-HID-Keyboard
|
||||
|
||||
Micropython library for the Bluetooth-HID-Keyboard
|
||||
=======================================================
|
||||
#https://github.com/Heerkog/MicroPythonBLEHID
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import bluetooth
|
||||
import struct, time
|
||||
from micropython import const
|
||||
from ubinascii import hexlify
|
||||
from ble_advertising import advertising_payload
|
||||
from bluetooth import UUID, FLAG_READ, FLAG_WRITE ,FLAG_NOTIFY, FLAG_WRITE_NO_RESPONSE
|
||||
|
||||
_IRQ_CENTRAL_CONNECT = const(1)
|
||||
_IRQ_CENTRAL_DISCONNECT = const(2)
|
||||
_IRQ_GATTS_WRITE = const(3)
|
||||
_IRQ_MTU_EXCHANGED = const(21)
|
||||
_IRQ_CONNECTION_UPDATE = const(27)
|
||||
_IRQ_GET_SECRET = const(29)
|
||||
_IRQ_SET_SECRET = const(30)
|
||||
_IRQ_PASSKEY_ACTION = const(31)
|
||||
_PASSKEY_ACTION_INPUT = const(2)
|
||||
_PASSKEY_ACTION_DISP = const(3)
|
||||
_PASSKEY_ACTION_NUMCMP = const(4)
|
||||
|
||||
_HID_INPUT_REPORT = const(b'\x05\x01\t\x06\xa1\x01\x85\x01u\x01\x95\x08\x05\x07\x19\xe0)\xe7\x15\x00%\x01\x81\x02\x95\x01u\x08\x81\x01\x95\x05u\x01\x05\x08\x19\x01)\x05\x91\x02\x95\x01u\x03\x91\x01\x95\x06u\x08\x15\x00%e\x05\x07\x19\x00)e\x81\x00\xc0')
|
||||
_KEYCODE = const(b'\x00\x00\x00\x00\x00\x00\x00\x00*+(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x00,\x9e\xb4\xa0\xa1\xa2\xa44\xa6\xa7\xa5\xae6-78\'\x1e\x1f !"#$%&\xb33\xb6.\xb7\xb8\x9f\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d/10\xa3\xad5\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\xaf\xb1\xb0\xb5L')
|
||||
|
||||
_DIS = (UUID(0x180A), ( (UUID(0x2A24), FLAG_READ),
|
||||
(UUID(0x2A25), FLAG_READ),
|
||||
(UUID(0x2A26), FLAG_READ),
|
||||
(UUID(0x2A27), FLAG_READ),
|
||||
(UUID(0x2A28), FLAG_READ),
|
||||
(UUID(0x2A29), FLAG_READ),
|
||||
(UUID(0x2A50), FLAG_READ), ), )
|
||||
|
||||
_BAS = (UUID(0x180F), ( (UUID(0x2A19), FLAG_READ | FLAG_NOTIFY, (
|
||||
(UUID(0x2902), 0x01 | 0x02),
|
||||
(UUID(0x2904), 0x01),)), ), )
|
||||
|
||||
_HIDS = (UUID(0x1812), ((UUID(0x2A4A), FLAG_READ),
|
||||
(UUID(0x2A4B), FLAG_READ),
|
||||
(UUID(0x2A4C), FLAG_READ | FLAG_WRITE | FLAG_WRITE_NO_RESPONSE),
|
||||
(UUID(0x2A4D), FLAG_READ | FLAG_NOTIFY, (
|
||||
(UUID(0x2902), 0x01 | 0x02),
|
||||
(UUID(0x2908), 0x01 | 0x02),)),
|
||||
(UUID(0x2A4D), FLAG_READ | FLAG_WRITE, (
|
||||
(UUID(0x2902), 0x01 | 0x02),
|
||||
(UUID(0x2908), 0x01 | 0x02),)),
|
||||
(UUID(0x2A4E), FLAG_READ | FLAG_WRITE | FLAG_WRITE_NO_RESPONSE), ), )
|
||||
|
||||
class Keyboard:
|
||||
def __init__(self, name=None, passkey=1234, battery_level=100):
|
||||
if (name is '') or (name is None):
|
||||
name = "Mixgo_" + self.mac[-6:].upper()
|
||||
print("Keyboard name:", name)
|
||||
|
||||
self._ble = bluetooth.BLE()
|
||||
self._ble.active(True)
|
||||
self._ble.irq(self._irq)
|
||||
self._ble.config(gap_name=name)
|
||||
self._ble.config(mtu=23)
|
||||
self.device_state = False
|
||||
self.conn_handle = None
|
||||
self.passkey = passkey
|
||||
self.battery_level = battery_level
|
||||
self.report = b'\x00'
|
||||
try:
|
||||
import ble_hid_key
|
||||
self.keys = ble_hid_key.keys
|
||||
except:
|
||||
self.keys = {}
|
||||
|
||||
handles = self._ble.gatts_register_services((_DIS, _BAS, _HIDS))
|
||||
self._service_characteristics(handles)
|
||||
self._payload = advertising_payload(name=name, services=[UUID(0x1812)], appearance=const(961))
|
||||
self.advertise()
|
||||
|
||||
def _irq(self, event, data):
|
||||
# Interrupt request callback function
|
||||
if event == _IRQ_CENTRAL_CONNECT:
|
||||
self.conn_handle, _, _ = data
|
||||
print("Keyboard connected: ", self.conn_handle)
|
||||
self.device_state = True
|
||||
elif event == _IRQ_CENTRAL_DISCONNECT:
|
||||
self.conn_handle = None
|
||||
conn_handle, addr_type, addr = data
|
||||
print("Keyboard disconnected: ", conn_handle)
|
||||
self.advertise()
|
||||
self.device_state = False
|
||||
elif event == _IRQ_MTU_EXCHANGED:
|
||||
conn_handle, mtu = data
|
||||
self._ble.config(mtu=mtu)
|
||||
print("MTU exchanged: ", mtu)
|
||||
elif event == _IRQ_CONNECTION_UPDATE:
|
||||
self.conn_handle, _, _, _, _ = data
|
||||
print("Connection update")
|
||||
elif event == _IRQ_PASSKEY_ACTION:
|
||||
conn_handle, action, passkey = data
|
||||
print("Passkey action", conn_handle, action, passkey)
|
||||
if action == _PASSKEY_ACTION_NUMCMP:
|
||||
self._ble.gap_passkey(conn_handle, action, False)
|
||||
elif action == _PASSKEY_ACTION_DISP:
|
||||
print("Displaying passkey")
|
||||
self._ble.gap_passkey(conn_handle, action, self.passkey)
|
||||
elif action == _PASSKEY_ACTION_INPUT:
|
||||
print(" Prompting for passkey")
|
||||
self._ble.gap_passkey(conn_handle, action, None)
|
||||
else:
|
||||
print("unknown action")
|
||||
elif event == _IRQ_GATTS_WRITE:
|
||||
conn_handle, attr_handle = data
|
||||
self.report = self._ble.gatts_read(attr_handle)
|
||||
elif event == _IRQ_SET_SECRET:
|
||||
sec_type, key, value = data
|
||||
key = sec_type, bytes(key)
|
||||
value = bytes(value) if value else None
|
||||
#print("Set secret: ", key, value)
|
||||
if value is None:
|
||||
if key in self.keys:
|
||||
del self.keys[key]
|
||||
self.key_secrets(self.keys)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
self.keys[key] = value
|
||||
self.key_secrets(self.keys)
|
||||
return True
|
||||
elif event == _IRQ_GET_SECRET:
|
||||
sec_type, index, key = data
|
||||
#print("Get secret: ", sec_type, index, bytes(key) if key else None)
|
||||
if key is None:
|
||||
i = 0
|
||||
for (t, _key), value in self.keys.items():
|
||||
if t == sec_type:
|
||||
if i == index:
|
||||
return value
|
||||
i += 1
|
||||
return None
|
||||
else:
|
||||
key = sec_type, bytes(key)
|
||||
return self.keys.get(key, None)
|
||||
#else:
|
||||
#print("Unhandled IRQ event: ", event, data)
|
||||
|
||||
def key_secrets(self, keys={}):
|
||||
with open("ble_hid_key.py", "w+") as s_f:
|
||||
s_f.write("keys=" + str(keys) + "\n")
|
||||
|
||||
def _service_characteristics(self, handles):
|
||||
(h_mod, h_ser, h_fwr, h_hwr, h_swr, h_man, h_pnp) = handles[0]
|
||||
(self.h_bat, h_ccc, h_bfmt,) = handles[1]
|
||||
(h_info, h_hid, _, self.h_rep, _, h_d1, _, _, h_d2, h_proto) = handles[2]
|
||||
|
||||
# Write DIS characteristics.
|
||||
self._ble.gatts_write(h_mod, b'1')
|
||||
self._ble.gatts_write(h_ser, b'1')
|
||||
self._ble.gatts_write(h_fwr, b'1')
|
||||
self._ble.gatts_write(h_hwr, b'1')
|
||||
self._ble.gatts_write(h_swr, b'1')
|
||||
self._ble.gatts_write(h_man, b'Homebrew')
|
||||
self._ble.gatts_write(h_pnp, struct.pack("<BHHH", 0x01, 0xFE61, 0x01, 0x0123))
|
||||
# Write BAS characteristics.
|
||||
self._ble.gatts_write(self.h_bat, struct.pack("<B", self.battery_level))
|
||||
self._ble.gatts_write(h_bfmt, b'\x04\x00\xad\x27\x01\x00\x00')
|
||||
self._ble.gatts_write(h_ccc, b'\x00\x00')
|
||||
# Write service characteristics
|
||||
self._ble.gatts_write(h_info, b"\x01\x01\x00\x02")
|
||||
self._ble.gatts_write(h_hid, _HID_INPUT_REPORT)
|
||||
self._ble.gatts_write(h_d1, b'\x01\x01')
|
||||
self._ble.gatts_write(h_d2, b'\x01\x02')
|
||||
self._ble.gatts_write(h_proto, b"\x01")
|
||||
|
||||
def state(self):
|
||||
return int.from_bytes(self.report, 'big')
|
||||
|
||||
def is_connected(self):
|
||||
return self.device_state
|
||||
|
||||
def advertise(self, interval_us=100000):
|
||||
print("Starting advertising")
|
||||
self._ble.gap_advertise(interval_us, adv_data=self._payload)
|
||||
|
||||
def notify_hid(self, special=0, general=0, release=True):
|
||||
if self.is_connected():
|
||||
_keys = bytearray(6)
|
||||
if type(general) in (tuple, list):
|
||||
for i in range(len(general)):
|
||||
if i > 5: break
|
||||
_keys[i] = general[i]
|
||||
else:
|
||||
_keys[0] = general
|
||||
# Pack the mouse state as described by the input report
|
||||
self._ble.gatts_notify(self.conn_handle, self.h_rep, bytes([special & 0xFF, 0]) + _keys)
|
||||
if release:
|
||||
time.sleep_ms(10)
|
||||
self._ble.gatts_notify(self.conn_handle, self.h_rep, b'\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||
|
||||
def notify_battery(self, level):
|
||||
if self.is_connected():
|
||||
self.battery_level = max(min(level, 100), 0)
|
||||
# Notifies the client by writing to the battery level handle.
|
||||
self._ble.gatts_notify(self.conn_handle, self.h_bat, struct.pack("<B", self.battery_level))
|
||||
|
||||
def notify_str(self, string, delay=0):
|
||||
for char in str(string):
|
||||
char = max(min(ord(char), 127), 0)
|
||||
self.notify_hid( 0x02 if _KEYCODE[char] >> 7 else 0x00, _KEYCODE[char] & 0x7F)
|
||||
time.sleep_ms(20 + delay)
|
||||
|
||||
@property
|
||||
def mac(self):
|
||||
'''Get mac address'''
|
||||
return hexlify(self._ble.config('mac')[1]).decode()
|
||||
193
mixly/boards/default/micropython/build/lib/ble_hid_mouse.py
Normal file
193
mixly/boards/default/micropython/build/lib/ble_hid_mouse.py
Normal file
@@ -0,0 +1,193 @@
|
||||
"""
|
||||
Bluetooth-HID-Mouse
|
||||
|
||||
Micropython library for the Bluetooth-HID-Mouse
|
||||
=======================================================
|
||||
#https://github.com/Heerkog/MicroPythonBLEHID
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import bluetooth
|
||||
import struct, time
|
||||
from micropython import const
|
||||
from ubinascii import hexlify
|
||||
from ble_advertising import advertising_payload
|
||||
from bluetooth import UUID, FLAG_READ, FLAG_WRITE ,FLAG_NOTIFY, FLAG_WRITE_NO_RESPONSE
|
||||
|
||||
_IRQ_CENTRAL_CONNECT = const(1)
|
||||
_IRQ_CENTRAL_DISCONNECT = const(2)
|
||||
_IRQ_MTU_EXCHANGED = const(21)
|
||||
_IRQ_CONNECTION_UPDATE = const(27)
|
||||
_IRQ_GET_SECRET = const(29)
|
||||
_IRQ_SET_SECRET = const(30)
|
||||
_IRQ_PASSKEY_ACTION = const(31)
|
||||
_PASSKEY_ACTION_INPUT = const(2)
|
||||
_PASSKEY_ACTION_DISP = const(3)
|
||||
_PASSKEY_ACTION_NUMCMP = const(4)
|
||||
|
||||
_HID_INPUT_REPORT = const(b'\x05\x01\t\x02\xa1\x01\x85\x01\t\x01\xa1\x00\x05\t\x19\x01)\x03\x15\x00%\x01\x95\x03u\x01\x81\x02\x95\x01u\x05\x81\x03\x05\x01\t0\t1\t8\x15\x81%\x7fu\x08\x95\x03\x81\x06\xc0\xc0')
|
||||
|
||||
_DIS = (UUID(0x180A), ( (UUID(0x2A24), FLAG_READ),
|
||||
(UUID(0x2A25), FLAG_READ),
|
||||
(UUID(0x2A26), FLAG_READ),
|
||||
(UUID(0x2A27), FLAG_READ),
|
||||
(UUID(0x2A28), FLAG_READ),
|
||||
(UUID(0x2A29), FLAG_READ),
|
||||
(UUID(0x2A50), FLAG_READ), ), )
|
||||
|
||||
_BAS = (UUID(0x180F), ( (UUID(0x2A19), FLAG_READ | FLAG_NOTIFY, (
|
||||
(UUID(0x2902), 0x01 | 0x02),
|
||||
(UUID(0x2904), 0x01),)), ), )
|
||||
|
||||
_HIDS = (UUID(0x1812), ((UUID(0x2A4A), FLAG_READ),
|
||||
(UUID(0x2A4B), FLAG_READ),
|
||||
(UUID(0x2A4C), FLAG_READ | FLAG_WRITE | FLAG_WRITE_NO_RESPONSE),
|
||||
(UUID(0x2A4D), FLAG_READ | FLAG_NOTIFY, (
|
||||
(UUID(0x2902), 0x01 | 0x02),
|
||||
(UUID(0x2908), 0x01 | 0x02), )),
|
||||
(UUID(0x2A4E), FLAG_READ | FLAG_WRITE | FLAG_WRITE_NO_RESPONSE), ), )
|
||||
|
||||
class Mouse:
|
||||
def __init__(self, name=None, passkey=1234, battery_level=100):
|
||||
if (name is '') or (name is None):
|
||||
name = "Mixgo_" + self.mac[-6:].upper()
|
||||
print("Mouse name:", name)
|
||||
|
||||
self._ble = bluetooth.BLE()
|
||||
self._ble.active(True)
|
||||
self._ble.irq(self._irq)
|
||||
self._ble.config(gap_name=name)
|
||||
self._ble.config(mtu=23)
|
||||
self.device_state = False
|
||||
self.conn_handle = None
|
||||
self.passkey = passkey
|
||||
self.battery_level = battery_level
|
||||
try:
|
||||
import ble_hid_key
|
||||
self.keys = ble_hid_key.keys
|
||||
except:
|
||||
self.keys = {}
|
||||
|
||||
handles = self._ble.gatts_register_services((_DIS, _BAS, _HIDS))
|
||||
self._service_characteristics(handles)
|
||||
self._payload = advertising_payload(name=name, services=[UUID(0x1812)], appearance=const(962))
|
||||
self.advertise()
|
||||
|
||||
def _irq(self, event, data):
|
||||
# Interrupt request callback function
|
||||
if event == _IRQ_CENTRAL_CONNECT:
|
||||
self.conn_handle, _, _ = data
|
||||
print("Mouse connected: ", self.conn_handle)
|
||||
self.device_state = True
|
||||
elif event == _IRQ_CENTRAL_DISCONNECT:
|
||||
self.conn_handle = None
|
||||
conn_handle, addr_type, addr = data
|
||||
print("Mouse disconnected: ", conn_handle)
|
||||
self.advertise()
|
||||
self.device_state = False
|
||||
elif event == _IRQ_MTU_EXCHANGED:
|
||||
conn_handle, mtu = data
|
||||
self._ble.config(mtu=mtu)
|
||||
print("MTU exchanged: ", mtu)
|
||||
elif event == _IRQ_CONNECTION_UPDATE:
|
||||
self.conn_handle, _, _, _, _ = data
|
||||
print("Connection update")
|
||||
elif event == _IRQ_PASSKEY_ACTION:
|
||||
conn_handle, action, passkey = data
|
||||
print("Passkey action", conn_handle, action, passkey)
|
||||
if action == _PASSKEY_ACTION_NUMCMP:
|
||||
self._ble.gap_passkey(conn_handle, action, False)
|
||||
elif action == _PASSKEY_ACTION_DISP:
|
||||
print("Displaying passkey")
|
||||
self._ble.gap_passkey(conn_handle, action, self.passkey)
|
||||
elif action == _PASSKEY_ACTION_INPUT:
|
||||
print(" Prompting for passkey")
|
||||
self._ble.gap_passkey(conn_handle, action, None)
|
||||
else:
|
||||
print("unknown action")
|
||||
elif event == _IRQ_SET_SECRET:
|
||||
sec_type, key, value = data
|
||||
key = sec_type, bytes(key)
|
||||
value = bytes(value) if value else None
|
||||
#print("Set secret: ", key, value)
|
||||
if value is None:
|
||||
if key in self.keys:
|
||||
del self.keys[key]
|
||||
self.key_secrets(self.keys)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
self.keys[key] = value
|
||||
self.key_secrets(self.keys)
|
||||
return True
|
||||
elif event == _IRQ_GET_SECRET:
|
||||
sec_type, index, key = data
|
||||
#print("Get secret: ", sec_type, index, bytes(key) if key else None)
|
||||
if key is None:
|
||||
i = 0
|
||||
for (t, _key), value in self.keys.items():
|
||||
if t == sec_type:
|
||||
if i == index:
|
||||
return value
|
||||
i += 1
|
||||
return None
|
||||
else:
|
||||
key = sec_type, bytes(key)
|
||||
return self.keys.get(key, None)
|
||||
#else:
|
||||
#print("Unhandled IRQ event: ", event, data)
|
||||
|
||||
def key_secrets(self, keys={}):
|
||||
with open("ble_hid_key.py", "w+") as s_f:
|
||||
s_f.write("keys=" + str(keys) + "\n")
|
||||
|
||||
def _service_characteristics(self, handles):
|
||||
(h_mod, h_ser, h_fwr, h_hwr, h_swr, h_man, h_pnp) = handles[0]
|
||||
(self.h_bat, h_ccc, h_bfmt,) = handles[1]
|
||||
(h_info, h_hid, h_ctrl, self.h_rep, _, h_d1, h_proto) = handles[2]
|
||||
|
||||
# Write DIS characteristics.
|
||||
self._ble.gatts_write(h_mod, b'1')
|
||||
self._ble.gatts_write(h_ser, b'1')
|
||||
self._ble.gatts_write(h_fwr, b'1')
|
||||
self._ble.gatts_write(h_hwr, b'1')
|
||||
self._ble.gatts_write(h_swr, b'1')
|
||||
self._ble.gatts_write(h_man, b'Homebrew')
|
||||
self._ble.gatts_write(h_pnp, struct.pack("<BHHH", 0x01, 0xFE61, 0x01, 0x0123))
|
||||
# Write BAS characteristics.
|
||||
self._ble.gatts_write(self.h_bat, struct.pack("<B", self.battery_level))
|
||||
self._ble.gatts_write(h_bfmt, b'\x04\x00\xad\x27\x01\x00\x00')
|
||||
self._ble.gatts_write(h_ccc, b'\x00\x00')
|
||||
# Write service characteristics
|
||||
self._ble.gatts_write(h_info, b"\x01\x01\x00\x02")
|
||||
self._ble.gatts_write(h_hid, _HID_INPUT_REPORT)
|
||||
self._ble.gatts_write(self.h_rep, b'\x00\x00\x00\x00')
|
||||
self._ble.gatts_write(h_d1, b'\x01\x01')
|
||||
self._ble.gatts_write(h_proto, b"\x01")
|
||||
|
||||
def is_connected(self):
|
||||
return self.device_state
|
||||
|
||||
def advertise(self, interval_us=100000):
|
||||
print("Starting advertising")
|
||||
self._ble.gap_advertise(interval_us, adv_data=self._payload)
|
||||
|
||||
def notify_hid(self, keys=0, move=(0, 0), wheel=0, release=True):
|
||||
if self.is_connected():
|
||||
# Pack the mouse state as described by the input report
|
||||
self._ble.gatts_notify(self.conn_handle, self.h_rep, bytes([keys & 0x0F, move[0] & 0xFF, move[1] & 0xFF, wheel & 0xFF]))
|
||||
if release:
|
||||
time.sleep_ms(10)
|
||||
self._ble.gatts_notify(self.conn_handle, self.h_rep, b'\x00\x00\x00\x00')
|
||||
|
||||
def notify_battery(self, level):
|
||||
if self.is_connected():
|
||||
self.battery_level = max(min(level, 100), 0)
|
||||
# Notifies the client by writing to the battery level handle.
|
||||
self._ble.gatts_notify(self.conn_handle, self.h_bat, struct.pack("<B", self.battery_level))
|
||||
|
||||
@property
|
||||
def mac(self):
|
||||
'''Get mac address'''
|
||||
return hexlify(self._ble.config('mac')[1]).decode()
|
||||
91
mixly/boards/default/micropython/build/lib/ble_peripheral.py
Normal file
91
mixly/boards/default/micropython/build/lib/ble_peripheral.py
Normal file
@@ -0,0 +1,91 @@
|
||||
"""
|
||||
Bluetooth-Peripheral
|
||||
|
||||
Micropython library for the Bluetooth-Peripheral
|
||||
=======================================================
|
||||
#Preliminary composition 20221018
|
||||
#https://github.com/micropython/micropython/tree/master/examples/bluetooth
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import bluetooth
|
||||
from micropython import const
|
||||
from ubinascii import hexlify
|
||||
from ble_advertising import advertising_payload
|
||||
|
||||
_IRQ_CENTRAL_CONNECT = const(1)
|
||||
_IRQ_CENTRAL_DISCONNECT = const(2)
|
||||
_IRQ_GATTS_WRITE = const(3)
|
||||
|
||||
_FLAG_READ = const(0x0002)
|
||||
_FLAG_WRITE_NO_RESPONSE = const(0x0004)
|
||||
_FLAG_WRITE = const(0x0008)
|
||||
_FLAG_NOTIFY = const(0x0010)
|
||||
|
||||
_UART_UUID = bluetooth.UUID(0x1101)
|
||||
_UART_TX = (bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"),_FLAG_READ | _FLAG_NOTIFY,)
|
||||
_UART_RX = (bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"),_FLAG_WRITE | _FLAG_WRITE_NO_RESPONSE,)
|
||||
_UART_SERVICE = (_UART_UUID,(_UART_TX, _UART_RX),)
|
||||
|
||||
class BLESimplePeripheral:
|
||||
def __init__(self, name=None):
|
||||
self._ble = bluetooth.BLE()
|
||||
self._ble.active(True)
|
||||
self._ble.irq(self._irq)
|
||||
((self._handle_tx, self._handle_rx),) = self._ble.gatts_register_services((_UART_SERVICE,))
|
||||
self._connections = set()
|
||||
self._write_callback = None
|
||||
self._write_data = None
|
||||
if (name is '') or (name is None):
|
||||
name = "Mixgo_" + self.mac[-6:].upper()
|
||||
print("Bluetooth name:", name)
|
||||
self._payload = advertising_payload(name=name, services=[_UART_UUID])
|
||||
self._advertise()
|
||||
|
||||
def _irq(self, event, data):
|
||||
# Track connections so we can send notifications.
|
||||
if event == _IRQ_CENTRAL_CONNECT:
|
||||
conn_handle, _, _ = data
|
||||
print("New connection", conn_handle)
|
||||
self._connections.add(conn_handle)
|
||||
elif event == _IRQ_CENTRAL_DISCONNECT:
|
||||
conn_handle, _, _ = data
|
||||
print("Disconnected", conn_handle)
|
||||
self._connections.remove(conn_handle)
|
||||
# Start advertising again to allow a new connection.
|
||||
self._advertise()
|
||||
elif event == _IRQ_GATTS_WRITE:
|
||||
conn_handle, value_handle = data
|
||||
value = self._ble.gatts_read(value_handle)
|
||||
if value_handle == self._handle_rx:
|
||||
try:
|
||||
self._write_data=value.decode().strip()
|
||||
except:
|
||||
self._write_data=value
|
||||
if self._write_callback:
|
||||
self._write_callback(self._write_data)
|
||||
|
||||
def send(self, data):
|
||||
for conn_handle in self._connections:
|
||||
self._ble.gatts_notify(conn_handle, self._handle_tx, data)
|
||||
|
||||
def is_connected(self):
|
||||
return len(self._connections) > 0
|
||||
|
||||
def _advertise(self, interval_us=500000):
|
||||
print("Starting advertising")
|
||||
self._ble.gap_advertise(interval_us, adv_data=self._payload)
|
||||
|
||||
def recv(self, callback= None):
|
||||
if callback:
|
||||
self._write_callback = callback
|
||||
else:
|
||||
write_data=self._write_data
|
||||
self._write_data=None
|
||||
return write_data
|
||||
|
||||
@property
|
||||
def mac(self):
|
||||
'''Get mac address'''
|
||||
return hexlify(self._ble.config('mac')[1]).decode()
|
||||
@@ -0,0 +1,86 @@
|
||||
"""
|
||||
Bluetooth-uart-Peripheral
|
||||
|
||||
Micropython library for the Bluetooth-uart-Peripheral
|
||||
=======================================================
|
||||
#Preliminary composition 202200628
|
||||
#https://github.com/micropython/micropython/tree/master/examples/bluetooth
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import bluetooth
|
||||
from ble_advertising import advertising_payload
|
||||
from micropython import const
|
||||
|
||||
_IRQ_CENTRAL_CONNECT = const(1)
|
||||
_IRQ_CENTRAL_DISCONNECT = const(2)
|
||||
_IRQ_GATTS_WRITE = const(3)
|
||||
|
||||
_FLAG_READ = const(0x0002)
|
||||
_FLAG_WRITE_NO_RESPONSE = const(0x0004)
|
||||
_FLAG_WRITE = const(0x0008)
|
||||
_FLAG_NOTIFY = const(0x0010)
|
||||
|
||||
_UART_UUID = bluetooth.UUID("0000fff0-0000-1000-8000-00805f9b34fb")
|
||||
_UART_TX = (bluetooth.UUID("0000fff1-0000-1000-8000-00805f9b34fb"),_FLAG_READ | _FLAG_NOTIFY,)
|
||||
_UART_RX = (bluetooth.UUID("0000fff2-0000-1000-8000-00805f9b34fb"),_FLAG_WRITE | _FLAG_WRITE_NO_RESPONSE,)
|
||||
_UART_SERVICE = (_UART_UUID,(_UART_TX, _UART_RX),)
|
||||
|
||||
class BLEUART:
|
||||
def __init__(self, name="mpy-uart", rxbuf=100):
|
||||
self._ble = bluetooth.BLE()
|
||||
self._ble.active(True)
|
||||
self._ble.irq(self._irq)
|
||||
((self._tx_handle, self._rx_handle),) = self._ble.gatts_register_services((_UART_SERVICE,))
|
||||
self._ble.gatts_set_buffer(self._rx_handle, rxbuf, True)
|
||||
self._connections = set()
|
||||
self._rx_buffer = bytearray()
|
||||
self._handler = None
|
||||
self._payload = advertising_payload(name=name, services=[_UART_UUID])
|
||||
self._advertise()
|
||||
|
||||
def irq(self, handler):
|
||||
self._handler = handler
|
||||
|
||||
def _irq(self, event, data):
|
||||
# Track connections so we can send notifications.
|
||||
if event == _IRQ_CENTRAL_CONNECT:
|
||||
conn_handle, _, _ = data
|
||||
print("Bluetooth connected")
|
||||
self._connections.add(conn_handle)
|
||||
elif event == _IRQ_CENTRAL_DISCONNECT:
|
||||
conn_handle, _, _ = data
|
||||
print("Bluetooth disconnected")
|
||||
if conn_handle in self._connections:
|
||||
self._connections.remove(conn_handle)
|
||||
# Start advertising again to allow a new connection.
|
||||
self._advertise()
|
||||
elif event == _IRQ_GATTS_WRITE:
|
||||
conn_handle, value_handle = data
|
||||
if conn_handle in self._connections and value_handle == self._rx_handle:
|
||||
self._rx_buffer += self._ble.gatts_read(self._rx_handle)
|
||||
if self._handler:
|
||||
self._handler()
|
||||
|
||||
def any(self):
|
||||
return len(self._rx_buffer)
|
||||
|
||||
def read(self, sz=None):
|
||||
if not sz:
|
||||
sz = len(self._rx_buffer)
|
||||
result = self._rx_buffer[0:sz]
|
||||
self._rx_buffer = self._rx_buffer[sz:]
|
||||
return result
|
||||
|
||||
def write(self, data):
|
||||
for conn_handle in self._connections:
|
||||
self._ble.gatts_notify(conn_handle, self._tx_handle, data)
|
||||
|
||||
def close(self):
|
||||
for conn_handle in self._connections:
|
||||
self._ble.gap_disconnect(conn_handle)
|
||||
self._connections.clear()
|
||||
|
||||
def _advertise(self, interval_us=500000):
|
||||
self._ble.gap_advertise(interval_us, adv_data=self._payload)
|
||||
67
mixly/boards/default/micropython/build/lib/ble_uart_repl.py
Normal file
67
mixly/boards/default/micropython/build/lib/ble_uart_repl.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# Proof-of-concept of a REPL over BLE UART.
|
||||
# Set the EoL characters to \r\n.
|
||||
|
||||
import io
|
||||
import os
|
||||
from machine import Timer
|
||||
from micropython import schedule
|
||||
from ble_uart_peripheral import BLEUART
|
||||
|
||||
_MP_STREAM_POLL = const(3)
|
||||
_MP_STREAM_POLL_RD = const(0x0001)
|
||||
|
||||
# Batch writes into 50ms intervals.
|
||||
Define_timer = Timer(2)
|
||||
|
||||
def schedule_in(handler, delay_ms):
|
||||
def _wrap(_arg):
|
||||
handler()
|
||||
if Define_timer:
|
||||
Define_timer.init(mode=Timer.ONE_SHOT, period=delay_ms, callback=_wrap)
|
||||
else:
|
||||
schedule(_wrap, None)
|
||||
|
||||
# Simple buffering stream to support the dupterm requirements.
|
||||
class BLEUARTStream(io.IOBase):
|
||||
def __init__(self, name="mpy-repl"):
|
||||
self._uart = BLEUART(name)
|
||||
self._tx_buf = bytearray()
|
||||
self._uart.irq(self._on_rx)
|
||||
|
||||
def _on_rx(self):
|
||||
if hasattr(os, "dupterm_notify"):
|
||||
os.dupterm_notify(None)
|
||||
|
||||
def read(self, sz=None):
|
||||
return self._uart.read(sz)
|
||||
|
||||
def readinto(self, buf):
|
||||
avail = self._uart.read(len(buf))
|
||||
if not avail:
|
||||
return None
|
||||
for i in range(len(avail)):
|
||||
buf[i] = avail[i]
|
||||
return len(avail)
|
||||
|
||||
def ioctl(self, op, arg):
|
||||
if op == _MP_STREAM_POLL:
|
||||
if self._uart.any():
|
||||
return _MP_STREAM_POLL_RD
|
||||
return 0
|
||||
|
||||
def _flush(self):
|
||||
data = self._tx_buf[0:100]
|
||||
self._tx_buf = self._tx_buf[100:]
|
||||
self._uart.write(data)
|
||||
if self._tx_buf:
|
||||
schedule_in(self._flush, 50)
|
||||
|
||||
def write(self, buf):
|
||||
empty = not self._tx_buf
|
||||
self._tx_buf += buf
|
||||
if empty:
|
||||
schedule_in(self._flush, 50)
|
||||
|
||||
def start(ble_name="mpy-repl"):
|
||||
stream = BLEUARTStream(name=ble_name)
|
||||
os.dupterm(stream)
|
||||
377
mixly/boards/default/micropython/build/lib/blynklib.py
Normal file
377
mixly/boards/default/micropython/build/lib/blynklib.py
Normal file
@@ -0,0 +1,377 @@
|
||||
# Copyright (c) 2019-2020 Anton Morozenko
|
||||
# Copyright (c) 2015-2019 Volodymyr Shymanskyy.
|
||||
# See the file LICENSE for copying permission.
|
||||
|
||||
__version__ = '0.2.6'
|
||||
|
||||
import usocket as socket
|
||||
import utime as time
|
||||
import ustruct as struct
|
||||
import uselect as select
|
||||
from micropython import const
|
||||
|
||||
ticks_ms = time.ticks_ms
|
||||
sleep_ms = time.sleep_ms
|
||||
|
||||
IOError = OSError
|
||||
|
||||
LOGO = """
|
||||
___ __ __
|
||||
/ _ )/ /_ _____ / /__
|
||||
/ _ / / // / _ \\/ '_/
|
||||
/____/_/\\_, /_//_/_/\\_\\
|
||||
/___/ for Python v{}\n""".format(__version__)
|
||||
|
||||
|
||||
def stub_log(*args):
|
||||
pass
|
||||
|
||||
|
||||
class BlynkError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class RedirectError(Exception):
|
||||
def __init__(self, server, port):
|
||||
self.server = server
|
||||
self.port = port
|
||||
|
||||
|
||||
class Protocol(object):
|
||||
MSG_RSP = const(0)
|
||||
MSG_LOGIN = const(2)
|
||||
MSG_PING = const(6)
|
||||
MSG_TWEET = const(12)
|
||||
MSG_EMAIL = const(13)
|
||||
MSG_NOTIFY = const(14)
|
||||
MSG_BRIDGE = const(15)
|
||||
MSG_HW_SYNC = const(16)
|
||||
MSG_INTERNAL = const(17)
|
||||
MSG_PROPERTY = const(19)
|
||||
MSG_HW = const(20)
|
||||
MSG_REDIRECT = const(41)
|
||||
MSG_HEAD_LEN = const(5)
|
||||
|
||||
STATUS_INVALID_TOKEN = const(9)
|
||||
STATUS_OK = const(200)
|
||||
VPIN_MAX_NUM = const(32)
|
||||
|
||||
_msg_id = 1
|
||||
|
||||
def _get_msg_id(self, **kwargs):
|
||||
if 'msg_id' in kwargs:
|
||||
return kwargs['msg_id']
|
||||
self._msg_id += const(1)
|
||||
return self._msg_id if self._msg_id <= const(0xFFFF) else const(1)
|
||||
|
||||
def _pack_msg(self, msg_type, *args, **kwargs):
|
||||
data = ('\0'.join([str(curr_arg) for curr_arg in args])).encode('utf-8')
|
||||
return struct.pack('!BHH', msg_type, self._get_msg_id(**kwargs), len(data)) + data
|
||||
|
||||
def parse_response(self, rsp_data, msg_buffer):
|
||||
msg_args = []
|
||||
msg_len = 0
|
||||
try:
|
||||
msg_type, msg_id, h_data = struct.unpack('!BHH', rsp_data[:self.MSG_HEAD_LEN])
|
||||
msg_len = self.MSG_HEAD_LEN + h_data
|
||||
except Exception as p_err:
|
||||
raise BlynkError('Message parse error: {}'.format(p_err))
|
||||
if msg_id == 0:
|
||||
raise BlynkError('invalid msg_id == 0')
|
||||
elif h_data >= msg_buffer:
|
||||
raise BlynkError('Command too long. Length = {}'.format(h_data))
|
||||
elif msg_type in (self.MSG_RSP, self.MSG_PING):
|
||||
pass
|
||||
elif msg_type in (self.MSG_HW, self.MSG_BRIDGE, self.MSG_INTERNAL, self.MSG_REDIRECT):
|
||||
msg_body = rsp_data[self.MSG_HEAD_LEN: msg_len]
|
||||
msg_args = [itm.decode('utf-8') for itm in msg_body.split(b'\0')]
|
||||
else:
|
||||
raise BlynkError("Unknown message type: '{}'".format(msg_type))
|
||||
return msg_type, msg_id, h_data, msg_args, msg_len
|
||||
|
||||
def heartbeat_msg(self, heartbeat, rcv_buffer):
|
||||
return self._pack_msg(self.MSG_INTERNAL, 'ver', __version__, 'buff-in', rcv_buffer, 'h-beat', heartbeat,
|
||||
'dev', 'mpython')
|
||||
|
||||
def login_msg(self, token):
|
||||
return self._pack_msg(self.MSG_LOGIN, token)
|
||||
|
||||
def ping_msg(self):
|
||||
return self._pack_msg(self.MSG_PING)
|
||||
|
||||
def response_msg(self, *args, **kwargs):
|
||||
return self._pack_msg(self.MSG_RSP, *args, **kwargs)
|
||||
|
||||
def virtual_write_msg(self, v_pin, *val):
|
||||
return self._pack_msg(self.MSG_HW, 'vw', v_pin, *val)
|
||||
|
||||
def virtual_sync_msg(self, *pins):
|
||||
return self._pack_msg(self.MSG_HW_SYNC, 'vr', *pins)
|
||||
|
||||
def email_msg(self, to, subject, body):
|
||||
return self._pack_msg(self.MSG_EMAIL, to, subject, body)
|
||||
|
||||
def tweet_msg(self, msg):
|
||||
return self._pack_msg(self.MSG_TWEET, msg)
|
||||
|
||||
def notify_msg(self, msg):
|
||||
return self._pack_msg(self.MSG_NOTIFY, msg)
|
||||
|
||||
def set_property_msg(self, pin, prop, *val):
|
||||
return self._pack_msg(self.MSG_PROPERTY, pin, prop, *val)
|
||||
|
||||
def internal_msg(self, *args):
|
||||
return self._pack_msg(self.MSG_INTERNAL, *args)
|
||||
|
||||
|
||||
class Connection(Protocol):
|
||||
SOCK_MAX_TIMEOUT = const(5)
|
||||
SOCK_TIMEOUT = 0.05
|
||||
EAGAIN = const(11)
|
||||
ETIMEDOUT = const(60)
|
||||
RETRIES_TX_DELAY = const(2)
|
||||
RETRIES_TX_MAX_NUM = const(3)
|
||||
RECONNECT_SLEEP = const(1)
|
||||
TASK_PERIOD_RES = const(50)
|
||||
DISCONNECTED = const(0)
|
||||
CONNECTING = const(1)
|
||||
AUTHENTICATING = const(2)
|
||||
AUTHENTICATED = const(3)
|
||||
|
||||
_state = None
|
||||
_socket = None
|
||||
_last_rcv_time = 0
|
||||
_last_ping_time = 0
|
||||
_last_send_time = 0
|
||||
|
||||
def __init__(self, token, server='blynk-cloud.com', port=80, heartbeat=10, rcv_buffer=1024, log=stub_log):
|
||||
self.token = token
|
||||
self.server = server
|
||||
self.port = port
|
||||
self.heartbeat = heartbeat
|
||||
self.rcv_buffer = rcv_buffer
|
||||
self.log = log
|
||||
|
||||
def _set_socket_timeout(self, timeout):
|
||||
if getattr(self._socket, 'settimeout', None):
|
||||
self._socket.settimeout(timeout)
|
||||
else:
|
||||
p = select.poll()
|
||||
p.register(self._socket)
|
||||
p.poll(int(timeout * const(1000)))
|
||||
|
||||
def send(self, data):
|
||||
retries = self.RETRIES_TX_MAX_NUM
|
||||
while retries > 0:
|
||||
try:
|
||||
retries -= 1
|
||||
self._last_send_time = ticks_ms()
|
||||
return self._socket.send(data)
|
||||
except (IOError, OSError):
|
||||
sleep_ms(self.RETRIES_TX_DELAY)
|
||||
|
||||
def receive(self, length, timeout):
|
||||
d_buff = b''
|
||||
try:
|
||||
self._set_socket_timeout(timeout)
|
||||
d_buff += self._socket.recv(length)
|
||||
if len(d_buff) >= length:
|
||||
d_buff = d_buff[:length]
|
||||
return d_buff
|
||||
except (IOError, OSError) as err:
|
||||
if str(err) == 'timed out':
|
||||
return b''
|
||||
if str(self.EAGAIN) in str(err) or str(self.ETIMEDOUT) in str(err):
|
||||
return b''
|
||||
raise
|
||||
|
||||
def is_server_alive(self):
|
||||
now = ticks_ms()
|
||||
h_beat_ms = self.heartbeat * const(1000)
|
||||
rcv_delta = time.ticks_diff(now, self._last_rcv_time)
|
||||
ping_delta = time.ticks_diff(now, self._last_ping_time)
|
||||
send_delta = time.ticks_diff(now, self._last_send_time)
|
||||
if rcv_delta > h_beat_ms + (h_beat_ms // const(2)):
|
||||
return False
|
||||
if (ping_delta > h_beat_ms // const(10)) and (send_delta > h_beat_ms or rcv_delta > h_beat_ms):
|
||||
self.send(self.ping_msg())
|
||||
self.log('Heartbeat time: {}'.format(now))
|
||||
self._last_ping_time = now
|
||||
return True
|
||||
|
||||
def _get_socket(self):
|
||||
try:
|
||||
self._state = self.CONNECTING
|
||||
self._socket = socket.socket()
|
||||
self._socket.connect(socket.getaddrinfo(self.server, self.port)[0][-1])
|
||||
self._set_socket_timeout(self.SOCK_TIMEOUT)
|
||||
self.log('Connected to server')
|
||||
except Exception as g_exc:
|
||||
raise BlynkError('Server connection failed: {}'.format(g_exc))
|
||||
|
||||
def _authenticate(self):
|
||||
self.log('Authenticating device...')
|
||||
self._state = self.AUTHENTICATING
|
||||
self.send(self.login_msg(self.token))
|
||||
rsp_data = self.receive(self.rcv_buffer, self.SOCK_MAX_TIMEOUT)
|
||||
if not rsp_data:
|
||||
raise BlynkError('Auth stage timeout')
|
||||
msg_type, _, status, args, _ = self.parse_response(rsp_data, self.rcv_buffer)
|
||||
if status != self.STATUS_OK:
|
||||
if status == self.STATUS_INVALID_TOKEN:
|
||||
raise BlynkError('Invalid Auth Token')
|
||||
if msg_type == self.MSG_REDIRECT:
|
||||
raise RedirectError(*args)
|
||||
raise BlynkError('Auth stage failed. Status={}'.format(status))
|
||||
self._state = self.AUTHENTICATED
|
||||
self.log('Access granted')
|
||||
|
||||
def _set_heartbeat(self):
|
||||
self.send(self.heartbeat_msg(self.heartbeat, self.rcv_buffer))
|
||||
rcv_data = self.receive(self.rcv_buffer, self.SOCK_MAX_TIMEOUT)
|
||||
if not rcv_data:
|
||||
raise BlynkError('Heartbeat stage timeout')
|
||||
_, _, status, _, _ = self.parse_response(rcv_data, self.rcv_buffer)
|
||||
if status != self.STATUS_OK:
|
||||
raise BlynkError('Set heartbeat returned code={}'.format(status))
|
||||
self.log('Heartbeat = {} sec. MaxCmdBuffer = {} bytes'.format(self.heartbeat, self.rcv_buffer))
|
||||
|
||||
def connected(self):
|
||||
return True if self._state == self.AUTHENTICATED else False
|
||||
|
||||
|
||||
class Blynk(Connection):
|
||||
_CONNECT_TIMEOUT = const(30) # 30sec
|
||||
_VPIN_WILDCARD = '*'
|
||||
_VPIN_READ = 'read v'
|
||||
_VPIN_WRITE = 'write v'
|
||||
_INTERNAL = 'internal_'
|
||||
_CONNECT = 'connect'
|
||||
_DISCONNECT = 'disconnect'
|
||||
_VPIN_READ_ALL = '{}{}'.format(_VPIN_READ, _VPIN_WILDCARD)
|
||||
_VPIN_WRITE_ALL = '{}{}'.format(_VPIN_WRITE, _VPIN_WILDCARD)
|
||||
_events = {}
|
||||
|
||||
def __init__(self, token, **kwargs):
|
||||
Connection.__init__(self, token, **kwargs)
|
||||
self._start_time = ticks_ms()
|
||||
self._last_rcv_time = ticks_ms()
|
||||
self._last_send_time = ticks_ms()
|
||||
self._last_ping_time = ticks_ms()
|
||||
self._state = self.DISCONNECTED
|
||||
print(LOGO)
|
||||
|
||||
def connect(self, timeout=_CONNECT_TIMEOUT):
|
||||
end_time = time.time() + timeout
|
||||
while not self.connected():
|
||||
if self._state == self.DISCONNECTED:
|
||||
try:
|
||||
self._get_socket()
|
||||
self._authenticate()
|
||||
self._set_heartbeat()
|
||||
self._last_rcv_time = ticks_ms()
|
||||
self.log('Registered events: {}\n'.format(list(self._events.keys())))
|
||||
self.call_handler(self._CONNECT)
|
||||
return True
|
||||
except BlynkError as b_err:
|
||||
self.disconnect(b_err)
|
||||
sleep_ms(self.TASK_PERIOD_RES)
|
||||
except RedirectError as r_err:
|
||||
self.disconnect()
|
||||
self.server = r_err.server
|
||||
self.port = r_err.port
|
||||
sleep_ms(self.TASK_PERIOD_RES)
|
||||
if time.time() >= end_time:
|
||||
return False
|
||||
|
||||
def disconnect(self, err_msg=None):
|
||||
self.call_handler(self._DISCONNECT)
|
||||
if self._socket:
|
||||
self._socket.close()
|
||||
self._state = self.DISCONNECTED
|
||||
if err_msg:
|
||||
self.log('[ERROR]: {}\nConnection closed'.format(err_msg))
|
||||
time.sleep(self.RECONNECT_SLEEP)
|
||||
|
||||
def virtual_write(self, v_pin, *val):
|
||||
return self.send(self.virtual_write_msg(v_pin, *val))
|
||||
|
||||
def virtual_sync(self, *v_pin):
|
||||
return self.send(self.virtual_sync_msg(*v_pin))
|
||||
|
||||
def email(self, to, subject, body):
|
||||
return self.send(self.email_msg(to, subject, body))
|
||||
|
||||
def tweet(self, msg):
|
||||
return self.send(self.tweet_msg(msg))
|
||||
|
||||
def notify(self, msg):
|
||||
return self.send(self.notify_msg(msg))
|
||||
|
||||
def set_property(self, v_pin, property_name, *val):
|
||||
return self.send(self.set_property_msg(v_pin, property_name, *val))
|
||||
|
||||
def internal(self, *args):
|
||||
return self.send(self.internal_msg(*args))
|
||||
|
||||
def handle_event(blynk, event_name):
|
||||
class Deco(object):
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
# wildcard 'read V*' and 'write V*' events handling
|
||||
if str(event_name).lower() in (blynk._VPIN_READ_ALL, blynk._VPIN_WRITE_ALL):
|
||||
event_base_name = str(event_name).split(blynk._VPIN_WILDCARD)[0]
|
||||
for i in range(blynk.VPIN_MAX_NUM + 1):
|
||||
blynk._events['{}{}'.format(event_base_name.lower(), i)] = func
|
||||
else:
|
||||
blynk._events[str(event_name).lower()] = func
|
||||
|
||||
def __call__(self):
|
||||
return self.func()
|
||||
|
||||
return Deco
|
||||
|
||||
def call_handler(self, event, *args, **kwargs):
|
||||
if event in self._events.keys():
|
||||
self.log("Event: ['{}'] -> {}".format(event, args))
|
||||
self._events[event](*args, **kwargs)
|
||||
|
||||
def process(self, msg_type, msg_id, msg_len, msg_args):
|
||||
if msg_type == self.MSG_RSP:
|
||||
self.log('Response status: {}'.format(msg_len))
|
||||
elif msg_type == self.MSG_PING:
|
||||
self.send(self.response_msg(self.STATUS_OK, msg_id=msg_id))
|
||||
elif msg_type in (self.MSG_HW, self.MSG_BRIDGE, self.MSG_INTERNAL):
|
||||
if msg_type == self.MSG_INTERNAL:
|
||||
self.call_handler("{}{}".format(self._INTERNAL, msg_args[0]), msg_args[1:])
|
||||
elif len(msg_args) >= const(3) and msg_args[0] == 'vw':
|
||||
self.call_handler("{}{}".format(self._VPIN_WRITE, msg_args[1]), int(msg_args[1]), msg_args[2:])
|
||||
elif len(msg_args) == const(2) and msg_args[0] == 'vr':
|
||||
self.call_handler("{}{}".format(self._VPIN_READ, msg_args[1]), int(msg_args[1]))
|
||||
|
||||
def read_response(self, timeout=0.5):
|
||||
end_time = time.ticks_ms() + int(timeout * const(1000))
|
||||
while time.ticks_diff(end_time, time.ticks_ms()) > 0:
|
||||
rsp_data = self.receive(self.rcv_buffer, self.SOCK_TIMEOUT)
|
||||
if rsp_data:
|
||||
self._last_rcv_time = ticks_ms()
|
||||
while rsp_data:
|
||||
msg_type, msg_id, h_data, msg_args, msg_len = self.parse_response(rsp_data, self.rcv_buffer)
|
||||
self.process(msg_type, msg_id, h_data, msg_args)
|
||||
rsp_data = rsp_data[msg_len:]
|
||||
|
||||
def run(self):
|
||||
if not self.connected():
|
||||
self.connect()
|
||||
else:
|
||||
try:
|
||||
self.read_response(timeout=self.SOCK_TIMEOUT)
|
||||
if not self.is_server_alive():
|
||||
self.disconnect('Server is offline')
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except BlynkError as b_err:
|
||||
self.log(b_err)
|
||||
self.disconnect()
|
||||
except Exception as g_exc:
|
||||
self.log(g_exc)
|
||||
133
mixly/boards/default/micropython/build/lib/blynktimer.py
Normal file
133
mixly/boards/default/micropython/build/lib/blynktimer.py
Normal file
@@ -0,0 +1,133 @@
|
||||
# Copyright (c) 2019-2020 Anton Morozenko
|
||||
"""
|
||||
Polling timers for functions.
|
||||
Registers timers and performs run once or periodical function execution after defined time intervals.
|
||||
"""
|
||||
# select.select call used as polling waiter where it is possible
|
||||
# cause time.sleep sometimes may load CPU up to 100% with small polling wait interval
|
||||
try:
|
||||
# cpython
|
||||
import time
|
||||
import select
|
||||
|
||||
polling_wait = lambda x: select.select([], [], [], x)
|
||||
polling_wait(0.01)
|
||||
except OSError:
|
||||
# windows case where select.select call fails
|
||||
polling_wait = lambda x: time.sleep(x)
|
||||
|
||||
except ImportError:
|
||||
# micropython
|
||||
import utime as time
|
||||
|
||||
try:
|
||||
from uselect import select as s_select
|
||||
|
||||
polling_wait = lambda x: s_select([], [], [], x)
|
||||
except ImportError:
|
||||
# case when micropython port does not support select.select
|
||||
polling_wait = lambda x: time.sleep(x)
|
||||
|
||||
WAIT_SEC = 0.05
|
||||
MAX_TIMERS = 16
|
||||
DEFAULT_INTERVAL = 10
|
||||
|
||||
|
||||
class TimerError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Timer(object):
|
||||
timers = {}
|
||||
|
||||
def __init__(self, no_timers_err=True):
|
||||
self.no_timers_err = no_timers_err
|
||||
|
||||
def _get_func_name(self, obj):
|
||||
"""retrieves a suitable name for a function"""
|
||||
if hasattr(obj, 'func'):
|
||||
# handles nested decorators
|
||||
return self._get_func_name(obj.func)
|
||||
# simply returns 'timer' if on port without function attrs
|
||||
return getattr(obj, '__name__', 'timer')
|
||||
|
||||
def register(blynk, *args, **kwargs):
|
||||
# kwargs with defaults are used cause PEP 3102 no supported by Python2
|
||||
interval = kwargs.pop('interval', DEFAULT_INTERVAL)
|
||||
run_once = kwargs.pop('run_once', False)
|
||||
stopped = kwargs.pop('stopped', False)
|
||||
|
||||
class Deco(object):
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
if len(list(Timer.timers.keys())) >= MAX_TIMERS:
|
||||
raise TimerError('Max allowed timers num={}'.format(MAX_TIMERS))
|
||||
_timer = _Timer(interval, func, run_once, stopped, *args, **kwargs)
|
||||
Timer.timers['{}_{}'.format(len(list(Timer.timers.keys())), blynk._get_func_name(func))] = _timer
|
||||
|
||||
def __call__(self, *f_args, **f_kwargs):
|
||||
return self.func(*f_args, **f_kwargs)
|
||||
|
||||
return Deco
|
||||
|
||||
@staticmethod
|
||||
def stop(t_id):
|
||||
timer = Timer.timers.get(t_id, None)
|
||||
if timer is None:
|
||||
raise TimerError('Timer id={} not found'.format(t_id))
|
||||
Timer.timers[t_id].stopped = True
|
||||
|
||||
@staticmethod
|
||||
def start(t_id):
|
||||
timer = Timer.timers.get(t_id, None)
|
||||
if timer is None:
|
||||
raise TimerError('Timer id={} not found'.format(t_id))
|
||||
Timer.timers[t_id].stopped = False
|
||||
Timer.timers[t_id].fire_time = None
|
||||
Timer.timers[t_id].fire_time_prev = None
|
||||
|
||||
@staticmethod
|
||||
def is_stopped(t_id):
|
||||
timer = Timer.timers.get(t_id, None)
|
||||
if timer is None:
|
||||
raise TimerError('Timer id={} not found'.format(t_id))
|
||||
return timer.stopped
|
||||
|
||||
def get_timers(self):
|
||||
states = {True: 'Stopped', False: 'Running'}
|
||||
return {k: states[v.stopped] for k, v in self.timers.items()}
|
||||
|
||||
def run(self):
|
||||
polling_wait(WAIT_SEC)
|
||||
timers_intervals = [curr_timer.run() for curr_timer in Timer.timers.values() if not curr_timer.stopped]
|
||||
if not timers_intervals and self.no_timers_err:
|
||||
raise TimerError('Running timers not found')
|
||||
return timers_intervals
|
||||
|
||||
|
||||
class _Timer(object):
|
||||
def __init__(self, interval, deco, run_once, stopped, *args, **kwargs):
|
||||
self.interval = interval
|
||||
self.deco = deco
|
||||
self.args = args
|
||||
self.run_once = run_once
|
||||
self.kwargs = kwargs
|
||||
self.fire_time = None
|
||||
self.fire_time_prev = None
|
||||
self.stopped = stopped
|
||||
|
||||
def run(self):
|
||||
timer_real_interval = 0
|
||||
if self.fire_time is None:
|
||||
self.fire_time = time.time() + self.interval
|
||||
if self.fire_time_prev is None:
|
||||
self.fire_time_prev = time.time()
|
||||
curr_time = time.time()
|
||||
if curr_time >= self.fire_time:
|
||||
self.deco(*self.args, **self.kwargs)
|
||||
if self.run_once:
|
||||
self.stopped = True
|
||||
timer_real_interval = curr_time - self.fire_time_prev
|
||||
self.fire_time_prev = self.fire_time
|
||||
self.fire_time = curr_time + self.interval
|
||||
return timer_real_interval
|
||||
162
mixly/boards/default/micropython/build/lib/bmp280.py
Normal file
162
mixly/boards/default/micropython/build/lib/bmp280.py
Normal file
@@ -0,0 +1,162 @@
|
||||
from ustruct import unpack as unp
|
||||
import utime
|
||||
|
||||
# Power Modes
|
||||
NORMAL = 0
|
||||
BMP280_TEMP_OS_SKIP = 0
|
||||
BMP280_TEMP_OS_1 = 1
|
||||
BMP280_TEMP_OS_2 = 2
|
||||
BMP280_TEMP_OS_4 = 3
|
||||
BMP280_TEMP_OS_8 = 4
|
||||
BMP280_TEMP_OS_16 = 5
|
||||
BMP280_PRES_OS_SKIP = 0
|
||||
BMP280_PRES_OS_1 = 1
|
||||
BMP280_PRES_OS_2 = 2
|
||||
BMP280_PRES_OS_4 = 3
|
||||
BMP280_PRES_OS_8 = 4
|
||||
BMP280_PRES_OS_16 = 5
|
||||
# BMP280 Temperature Registers
|
||||
BMP280_REGISTER_DIG_T1 = 0x88
|
||||
BMP280_REGISTER_DIG_T2 = 0x8A
|
||||
BMP280_REGISTER_DIG_T3 = 0x8C
|
||||
# BMP280 Pressure Registers
|
||||
BMP280_REGISTER_DIG_P1 = 0x8E
|
||||
BMP280_REGISTER_DIG_P2 = 0x90
|
||||
BMP280_REGISTER_DIG_P3 = 0x92
|
||||
BMP280_REGISTER_DIG_P4 = 0x94
|
||||
BMP280_REGISTER_DIG_P5 = 0x96
|
||||
BMP280_REGISTER_DIG_P6 = 0x98
|
||||
BMP280_REGISTER_DIG_P7 = 0x9A
|
||||
BMP280_REGISTER_DIG_P8 = 0x9C
|
||||
BMP280_REGISTER_DIG_P9 = 0x9E
|
||||
BMP280_REGISTER_ID = 0xD0
|
||||
BMP280_REGISTER_RESET = 0xE0
|
||||
BMP280_REGISTER_STATUS = 0xF3
|
||||
BMP280_REGISTER_CONTROL = 0xF4
|
||||
BMP280_REGISTER_CONFIG = 0xF5 # IIR filter config
|
||||
BMP280_REGISTER_DATA = 0xF7
|
||||
|
||||
class BMP280:
|
||||
def __init__(self, i2c_bus, addr=0x77):
|
||||
self._bmp_i2c = i2c_bus
|
||||
self._i2c_addr = addr
|
||||
self.chip_id = self._read(BMP280_REGISTER_ID, 2)
|
||||
|
||||
self._T1 = unp('<H', self._read(BMP280_REGISTER_DIG_T1, 2))[0]
|
||||
self._T2 = unp('<h', self._read(BMP280_REGISTER_DIG_T2, 2))[0]
|
||||
self._T3 = unp('<h', self._read(BMP280_REGISTER_DIG_T3, 2))[0]
|
||||
self._P1 = unp('<H', self._read(BMP280_REGISTER_DIG_P1, 2))[0]
|
||||
self._P2 = unp('<h', self._read(BMP280_REGISTER_DIG_P2, 2))[0]
|
||||
self._P3 = unp('<h', self._read(BMP280_REGISTER_DIG_P3, 2))[0]
|
||||
self._P4 = unp('<h', self._read(BMP280_REGISTER_DIG_P4, 2))[0]
|
||||
self._P5 = unp('<h', self._read(BMP280_REGISTER_DIG_P5, 2))[0]
|
||||
self._P6 = unp('<h', self._read(BMP280_REGISTER_DIG_P6, 2))[0]
|
||||
self._P7 = unp('<h', self._read(BMP280_REGISTER_DIG_P7, 2))[0]
|
||||
self._P8 = unp('<h', self._read(BMP280_REGISTER_DIG_P8, 2))[0]
|
||||
self._P9 = unp('<h', self._read(BMP280_REGISTER_DIG_P9, 2))[0]
|
||||
|
||||
self._t_os = BMP280_TEMP_OS_2 # temperature oversampling
|
||||
self._p_os = BMP280_PRES_OS_16 # pressure oversampling
|
||||
# output raw
|
||||
self._t_raw = 0
|
||||
self._t_fine = 0
|
||||
self._t = 0
|
||||
self._p_raw = 0
|
||||
self._p = 0
|
||||
self._read_wait_ms = 100 # interval between forced measure and readout
|
||||
self._new_read_ms = 200 # interval between
|
||||
self._last_read_ts = 0
|
||||
|
||||
def _read(self, addr, size=1):
|
||||
return self._bmp_i2c.readfrom_mem(self._i2c_addr, addr, size)
|
||||
|
||||
def _write(self, addr, b_arr):
|
||||
if not type(b_arr) is bytearray:
|
||||
b_arr = bytearray([b_arr])
|
||||
return self._bmp_i2c.writeto_mem(self._i2c_addr, addr, b_arr)
|
||||
|
||||
def _gauge(self):
|
||||
# TODO limit new reads
|
||||
now = utime.ticks_ms()
|
||||
if utime.ticks_diff(now, self._last_read_ts) > self._new_read_ms:
|
||||
self._last_read_ts = now
|
||||
r = self._t_os + (self._p_os << 3) + (1 << 6)
|
||||
self._write(BMP280_REGISTER_CONTROL, r)
|
||||
utime.sleep_ms(100) # TODO calc sleep
|
||||
d = self._read(BMP280_REGISTER_DATA, 6) # read all data at once (as by spec)
|
||||
self._p_raw = (d[0] << 12) + (d[1] << 4) + (d[2] >> 4)
|
||||
self._t_raw = (d[3] << 12) + (d[4] << 4) + (d[5] >> 4)
|
||||
self._t_fine = 0
|
||||
self._t = 0
|
||||
self._p = 0
|
||||
|
||||
def load_test_calibration(self):
|
||||
self._T1 = 27504
|
||||
self._T2 = 26435
|
||||
self._T3 = -1000
|
||||
self._P1 = 36477
|
||||
self._P2 = -10685
|
||||
self._P3 = 3024
|
||||
self._P4 = 2855
|
||||
self._P5 = 140
|
||||
self._P6 = -7
|
||||
self._P7 = 15500
|
||||
self._P8 = -14600
|
||||
self._P9 = 6000
|
||||
|
||||
def load_test_data(self):
|
||||
self._t_raw = 519888
|
||||
self._p_raw = 415148
|
||||
|
||||
def print_calibration(self):
|
||||
print("T1: {} {}".format(self._T1, type(self._T1)))
|
||||
print("T2: {} {}".format(self._T2, type(self._T2)))
|
||||
print("T3: {} {}".format(self._T3, type(self._T3)))
|
||||
print("P1: {} {}".format(self._P1, type(self._P1)))
|
||||
print("P2: {} {}".format(self._P2, type(self._P2)))
|
||||
print("P3: {} {}".format(self._P3, type(self._P3)))
|
||||
print("P4: {} {}".format(self._P4, type(self._P4)))
|
||||
print("P5: {} {}".format(self._P5, type(self._P5)))
|
||||
print("P6: {} {}".format(self._P6, type(self._P6)))
|
||||
print("P7: {} {}".format(self._P7, type(self._P7)))
|
||||
print("P8: {} {}".format(self._P8, type(self._P8)))
|
||||
print("P9: {} {}".format(self._P9, type(self._P9)))
|
||||
|
||||
def _calc_t_fine(self):
|
||||
# From datasheet page 22
|
||||
self._gauge()
|
||||
if self._t_fine == 0:
|
||||
var1 = (((self._t_raw >> 3) - (self._T1 << 1)) * self._T2) >> 11
|
||||
var2 = (((((self._t_raw >> 4) - self._T1) * ((self._t_raw >> 4) - self._T1)) >> 12) * self._T3) >> 14
|
||||
self._t_fine = var1 + var2
|
||||
|
||||
# @property
|
||||
def get_BMP_temperature(self):
|
||||
self._calc_t_fine()
|
||||
if self._t == 0:
|
||||
self._t = ((self._t_fine * 5 + 128) >> 8) / 100.
|
||||
return self._t
|
||||
|
||||
# @property
|
||||
def get_BMP_pressure(self):
|
||||
# From datasheet page 22
|
||||
self._calc_t_fine()
|
||||
if self._p == 0:
|
||||
var1 = self._t_fine - 128000
|
||||
var2 = var1 * var1 * self._P6
|
||||
var2 = var2 + ((var1 * self._P5) << 17)
|
||||
var2 = var2 + (self._P4 << 35)
|
||||
var1 = ((var1 * var1 * self._P3) >> 8) + ((var1 * self._P2) << 12)
|
||||
var1 = (((1 << 47) + var1) * self._P1) >> 33
|
||||
|
||||
if var1 == 0:
|
||||
return 0
|
||||
|
||||
p = 1048576 - self._p_raw
|
||||
p = int((((p << 31) - var2) * 3125) / var1)
|
||||
var1 = (self._P9 * (p >> 13) * (p >> 13)) >> 25
|
||||
var2 = (self._P8 * p) >> 19
|
||||
|
||||
p = ((p + var1 + var2) >> 8) + (self._P7 << 4)
|
||||
self._p = p / 256.0
|
||||
return self._p
|
||||
117
mixly/boards/default/micropython/build/lib/cbr817.py
Normal file
117
mixly/boards/default/micropython/build/lib/cbr817.py
Normal file
@@ -0,0 +1,117 @@
|
||||
"""
|
||||
CBR817
|
||||
|
||||
MicroPython library for the CBR817 (Microwave radar sensor)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from machine import Pin
|
||||
from micropython import const
|
||||
|
||||
CBR_ADDRESS = const(0x71)
|
||||
CBR_OP_SET = const(0x02)
|
||||
CBR_TX_RF = const(0x03)
|
||||
CBR_POWER = const(0x04)
|
||||
CBR_LIGHT = const(0x0B)
|
||||
CBR_REG_CTR1 = const(0X13)
|
||||
CBR_SENSOR_THR = const(0X18)
|
||||
CBR_NOISE_THR = const(0X1A)
|
||||
CBR_TRIGER = const(0x1C)
|
||||
CBR_DELAY_TIM = const(0X1D)
|
||||
CBR_LOCK_TIM = const(0X20)
|
||||
CBR_SEL_REG = const(0x23)
|
||||
CBR_REG_CTR2 = const(0X24)
|
||||
CBR_FILTER = const(0x2A)
|
||||
CBR_RESULT = const(0x81)
|
||||
|
||||
class CBR817:
|
||||
def __init__(self, i2c_bus, addr=CBR_ADDRESS, tx_power=3, threshold=5000, noise=256, delay=500, lock=500):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
|
||||
self._configure()
|
||||
self.tx_power(tx_power)
|
||||
self.threshold(threshold)
|
||||
self.noise(noise)
|
||||
self.delay_ms(delay)
|
||||
self.lock_ms(lock)
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address, reg, val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes <= 1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _wake(self):
|
||||
'''Wake up from low power consumption'''
|
||||
try:
|
||||
self._wreg(CBR_SEL_REG, 0xC0)
|
||||
except :
|
||||
pass
|
||||
|
||||
def threshold(self, value=None):
|
||||
self._wake()
|
||||
if value is None:
|
||||
return self._rreg(CBR_SENSOR_THR) | self._rreg(CBR_SENSOR_THR + 1) << 8
|
||||
else:
|
||||
self._wreg(CBR_SENSOR_THR, value & 0xFF)
|
||||
self._wreg(CBR_SENSOR_THR + 1, (value >> 8) & 0xFF)
|
||||
|
||||
def noise(self, value=None):
|
||||
self._wake()
|
||||
if value is None:
|
||||
return self._rreg(CBR_NOISE_THR) | self._rreg(CBR_NOISE_THR + 1) << 8
|
||||
else:
|
||||
self._wreg(CBR_NOISE_THR, value & 0xFF)
|
||||
self._wreg(CBR_NOISE_THR + 1, (value >> 8) & 0xFF)
|
||||
|
||||
def delay_ms(self, value=None):
|
||||
self._wake()
|
||||
if value is None:
|
||||
return round((self._rreg(CBR_DELAY_TIM) | self._rreg(CBR_DELAY_TIM + 1) << 8 | self._rreg(CBR_DELAY_TIM + 2) << 16) / 32)
|
||||
else:
|
||||
value = value * 32
|
||||
self._wreg(CBR_DELAY_TIM, value & 0xFF)
|
||||
self._wreg(CBR_DELAY_TIM + 1, (value >> 8) & 0xFF)
|
||||
self._wreg(CBR_DELAY_TIM + 2, (value >> 16) & 0xFF)
|
||||
|
||||
def lock_ms(self, value=None):
|
||||
self._wake()
|
||||
if value is None:
|
||||
return round((self._rreg(CBR_LOCK_TIM) | self._rreg(CBR_LOCK_TIM + 1) << 8 | self._rreg(CBR_LOCK_TIM + 2) << 16) // 32)
|
||||
else:
|
||||
value = value * 32
|
||||
self._wreg(CBR_LOCK_TIM, value & 0xFF)
|
||||
self._wreg(CBR_LOCK_TIM + 1, (value >> 8) & 0xFF)
|
||||
self._wreg(CBR_LOCK_TIM + 2, (value >> 16) & 0xFF)
|
||||
|
||||
def tx_power(self, value=None):
|
||||
self._wake()
|
||||
if value is None:
|
||||
return self._rreg(CBR_TX_RF) & 0x07
|
||||
else:
|
||||
self._wreg(CBR_TX_RF, (value & 0x07) | 0x30)
|
||||
|
||||
def _configure(self):
|
||||
self._wake()
|
||||
self._wreg(CBR_SEL_REG, 0xC0) #唤醒射频芯片
|
||||
_star = time.ticks_ms()
|
||||
while self._rreg(CBR_SEL_REG) != 0xC0:
|
||||
self._wreg(CBR_SEL_REG, 0xC0)
|
||||
time.sleep_us(10)
|
||||
if time.ticks_diff(time.ticks_ms(), _star) >= 200:
|
||||
raise AttributeError("Cannot find a CBR817")
|
||||
self._wreg(CBR_TRIGER, 0x55) #连续检测
|
||||
self._wreg(CBR_LIGHT, 0x12) #关闭光敏
|
||||
self._wreg(CBR_POWER, 0xA0) #功耗全供电
|
||||
self._wreg(CBR_FILTER, 0x0F) #打开滤波器
|
||||
self._wreg(CBR_OP_SET, 0x5C) #单运放,0.5uA电流
|
||||
self._wreg(CBR_REG_CTR1, 0X61) #感应门限和噪声门限改寄存器控制
|
||||
self._wreg(CBR_REG_CTR2, 0X60) #延时时间和闭锁时间改寄存器控制
|
||||
|
||||
def result(self):
|
||||
self._wake()
|
||||
return bool(self._rreg(CBR_RESULT) & 0x20)
|
||||
85
mixly/boards/default/micropython/build/lib/cc_g1.py
Normal file
85
mixly/boards/default/micropython/build/lib/cc_g1.py
Normal file
@@ -0,0 +1,85 @@
|
||||
"""
|
||||
CC_G1
|
||||
|
||||
Micropython library for the CC_G1(Remote control handle)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20231222
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
from micropython import const
|
||||
from machine import Pin,SoftI2C
|
||||
|
||||
_CC_G1_ADDRESS = const(0x27)
|
||||
_CC_G1_ID = const(0x00)
|
||||
_CC_G1_VBAT = const(0x01)
|
||||
_CC_G1_ADC = const(0x03)
|
||||
_CC_G1_KEY = const(0x07)
|
||||
|
||||
class Handle:
|
||||
def __init__(self, i2c_bus, addr=_CC_G1_ADDRESS):
|
||||
self._i2c=i2c_bus
|
||||
self._addr = addr
|
||||
if self._rreg(_CC_G1_ID)!= 0x27:
|
||||
raise AttributeError("Cannot find a CC_G1")
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
try:
|
||||
self._i2c.writeto_mem(self._addr, reg, val.to_bytes(1, 'little'))
|
||||
except:
|
||||
return 0
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
try:
|
||||
self._i2c.writeto(self._addr, reg.to_bytes(1, 'little'))
|
||||
return self._i2c.readfrom(self._addr, nbytes)[0] if nbytes<=1 else self._i2c.readfrom(self._addr, nbytes)[0:nbytes]
|
||||
except:
|
||||
return 0
|
||||
|
||||
def read_bat(self, ratio=5/1023):
|
||||
'''Read battery power'''
|
||||
vbat = self._rreg(_CC_G1_VBAT)<<2 | self._rreg(_CC_G1_VBAT+1)>>6
|
||||
return round(vbat*ratio, 2)
|
||||
|
||||
def read_joystick(self, ratio=100/1023):
|
||||
'''Read joystick'''
|
||||
y_axis = 1023 - (self._rreg(_CC_G1_ADC) << 2 | self._rreg(_CC_G1_ADC + 1) >> 6)
|
||||
x_axis = self._rreg(_CC_G1_ADC + 2 ) << 2 | self._rreg(_CC_G1_ADC + 3) >> 6
|
||||
return round(x_axis*ratio), round(y_axis*ratio)
|
||||
|
||||
def read_key(self, index):
|
||||
'''Read key1~6'''
|
||||
if not 0 <= index <= 5:
|
||||
raise ValueError("The key number must be a number in the range: 0~5")
|
||||
if index<=4:
|
||||
return bool(self._rreg(_CC_G1_KEY) >> index & 0x01)
|
||||
else:
|
||||
return bool(self._rreg(_CC_G1_KEY) >> 7 & 0x01)
|
||||
|
||||
def shutdown(self, flag=True):
|
||||
"""This function is only available on battery power"""
|
||||
if flag:
|
||||
self._wreg(_CC_G1_KEY, (self._rreg(_CC_G1_KEY)) & 0XBF)
|
||||
else:
|
||||
self._wreg(_CC_G1_KEY, (self._rreg(_CC_G1_KEY)) | 0X40)
|
||||
|
||||
'''Select instantiation objects'''
|
||||
try:
|
||||
#MixGo CC/ME
|
||||
ext_i2c = SoftI2C(scl=Pin(0), sda=Pin(1), freq=100000)
|
||||
handle = Handle(ext_i2c)
|
||||
except:
|
||||
try:
|
||||
#MixGo CE
|
||||
ext_i2c = SoftI2C(scl=Pin(17), sda=Pin(18), freq=100000)
|
||||
handle = Handle(ext_i2c)
|
||||
except:
|
||||
try:
|
||||
#MixGo Mini
|
||||
ext_i2c = SoftI2C(scl=Pin(8), sda=Pin(7), freq=100000)
|
||||
handle = Handle(ext_i2c)
|
||||
except:
|
||||
print("MixGo board cannot find a CC_G1")
|
||||
147
mixly/boards/default/micropython/build/lib/ch914x_at.py
Normal file
147
mixly/boards/default/micropython/build/lib/ch914x_at.py
Normal file
@@ -0,0 +1,147 @@
|
||||
"""
|
||||
Bluetooth AT
|
||||
|
||||
Micropython library for the Bluetooth AT(WCH)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20230106
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
from machine import Pin
|
||||
from time import sleep_ms
|
||||
|
||||
class AT:
|
||||
def __init__(self, pin,times=5):
|
||||
self.at_pin = Pin(pin, Pin.OUT)
|
||||
self.at_pin.value(1)
|
||||
self._times = times
|
||||
self._flag = [0,0,0,0,0,0,0,0] #mac0,1 name2,3 power4,5 power6,7
|
||||
self._power = [0,1,2,3,-3,-8,-14,-20]
|
||||
sleep_ms(100)
|
||||
|
||||
def _str_reverse(self,data):
|
||||
data=data.split(':')
|
||||
data.reverse()
|
||||
data=":".join(data)
|
||||
return data
|
||||
|
||||
def ble_mac(self, mac=None):
|
||||
sleep_ms(200)
|
||||
if mac is None:
|
||||
if not (self._flag[0] >= self._times and self._times != 0):
|
||||
self._flag[0]+=1
|
||||
self.at_pin.value(0)
|
||||
sleep_ms(10)
|
||||
data=input('AT+MAC?\r\n')
|
||||
input()
|
||||
self.at_pin.value(1)
|
||||
print('BLE_MAC:',self._str_reverse(data))
|
||||
sleep_ms(100)
|
||||
return self._str_reverse(data)
|
||||
else:
|
||||
print('Please delete this command and upload other programs again')
|
||||
else:
|
||||
if not (self._flag[1] >= self._times and self._times != 0):
|
||||
self._flag[1]+=1
|
||||
self.at_pin.value(0)
|
||||
sleep_ms(10)
|
||||
data=input('AT+MAC={}\r\n'.format(self._str_reverse(mac)))
|
||||
print('\r\n')
|
||||
self.at_pin.value(1)
|
||||
print('BLE_MAC:',mac,data)
|
||||
sleep_ms(100)
|
||||
return True if data is "OK" else False
|
||||
else:
|
||||
print('Please delete this command and upload other programs again')
|
||||
|
||||
def ble_name(self, name=None):
|
||||
sleep_ms(200)
|
||||
if name is None:
|
||||
if not (self._flag[2] >= self._times and self._times != 0):
|
||||
self._flag[2]+=1
|
||||
self.at_pin.value(0)
|
||||
sleep_ms(10)
|
||||
data=input('AT+NAME?\r\n')
|
||||
input()
|
||||
input()
|
||||
self.at_pin.value(1)
|
||||
print('BLE_NAME:',data)
|
||||
sleep_ms(100)
|
||||
return data
|
||||
else:
|
||||
print('Please delete this command and upload other programs again')
|
||||
else:
|
||||
if not (self._flag[3] >= self._times and self._times != 0):
|
||||
self._flag[3]+=1
|
||||
self.at_pin.value(0)
|
||||
sleep_ms(10)
|
||||
data=input('AT+NAME='+name+'\r\n')
|
||||
print('\r\n')
|
||||
self.at_pin.value(1)
|
||||
print('BLE_NAME:',name,data)
|
||||
sleep_ms(100)
|
||||
return True if data is "OK" else False
|
||||
else:
|
||||
print('Please delete this command and upload other programs again')
|
||||
|
||||
def ble_power(self, power=None):
|
||||
sleep_ms(200)
|
||||
if power is None:
|
||||
if not (self._flag[4] >= self._times and self._times != 0):
|
||||
self._flag[4]+=1
|
||||
self.at_pin.value(0)
|
||||
sleep_ms(10)
|
||||
data=input('AT+TPL?\r\n')
|
||||
input()
|
||||
print(' \r\n')
|
||||
self.at_pin.value(1)
|
||||
data=self._power[int(data[4:])]
|
||||
print('BLE_Power: {}DB'.format(data))
|
||||
sleep_ms(100)
|
||||
return data
|
||||
else:
|
||||
print('Please delete this command and upload other programs again')
|
||||
else:
|
||||
if not (self._flag[5] >= self._times and self._times != 0):
|
||||
self._flag[5]+=1
|
||||
self.at_pin.value(0)
|
||||
sleep_ms(10)
|
||||
data=input('AT+TPL={}\r\n'.format(self._power.index(power)))
|
||||
print('\r\n')
|
||||
self.at_pin.value(1)
|
||||
print('BLE_Power:',str(power)+'DB',data)
|
||||
sleep_ms(100)
|
||||
return True if data is "OK" else False
|
||||
else:
|
||||
print('Please delete this command and upload other programs again')
|
||||
|
||||
def ble_pname(self, name=None):
|
||||
sleep_ms(200)
|
||||
if name is None:
|
||||
if not (self._flag[6] >= self._times and self._times != 0):
|
||||
self._flag[6]+=1
|
||||
self.at_pin.value(0)
|
||||
sleep_ms(10)
|
||||
data=input('AT+PNAME?\r\n')
|
||||
input()
|
||||
input()
|
||||
self.at_pin.value(1)
|
||||
print('BLE_PNAME:',data)
|
||||
sleep_ms(100)
|
||||
return data
|
||||
else:
|
||||
print('Please delete this command and upload other programs again')
|
||||
else:
|
||||
if not (self._flag[7] >= self._times and self._times != 0):
|
||||
self._flag[7]+=1
|
||||
self.at_pin.value(0)
|
||||
sleep_ms(10)
|
||||
data=input('AT+PNAME='+name+'\r\n')
|
||||
print('\r\n')
|
||||
self.at_pin.value(1)
|
||||
print('BLE_PNAME:',name,data)
|
||||
sleep_ms(100)
|
||||
return True if data is "OK" else False
|
||||
else:
|
||||
print('Please delete this command and upload other programs again')
|
||||
129
mixly/boards/default/micropython/build/lib/ci130x.py
Normal file
129
mixly/boards/default/micropython/build/lib/ci130x.py
Normal file
@@ -0,0 +1,129 @@
|
||||
"""
|
||||
CI130X
|
||||
|
||||
MicroPython library for the CI130X (ASR-I2C)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from struct import pack
|
||||
from micropython import const
|
||||
|
||||
_CI_ADDRESS = const(0x64)
|
||||
_CI_ID_GET = const(0x02)
|
||||
_CI_ID_SET = const(0x03)
|
||||
_CI_ID_NUM = const(0x06)
|
||||
_CI_ID_CLE = const(0x07)
|
||||
_CI_ID_PACTRL = const(0x09)
|
||||
_CI_ID_ASREN = const(0x0A)
|
||||
_CI_ID_END = const(0x5A)
|
||||
_TIME_SNUM = const(0x75)
|
||||
|
||||
class CI130X:
|
||||
def __init__(self, i2c_bus, addr=_CI_ADDRESS):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
self._cmd_id = None
|
||||
self._enable = True
|
||||
try:
|
||||
self._rreg(_CI_ID_GET, 3)
|
||||
except:
|
||||
try: #C130X 启动慢,加延时判断
|
||||
time.sleep_ms(850)
|
||||
self._rreg(_CI_ID_GET, 3)
|
||||
except:
|
||||
raise AttributeError("Cannot find a CI130X")
|
||||
|
||||
def _wreg(self, reg):
|
||||
'''Write memory address'''
|
||||
self._device.writeto(self._address, reg)
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)
|
||||
|
||||
def status(self):
|
||||
"""返回 (是否唤醒, 是否播放)"""
|
||||
_buf = self._rreg(_CI_ID_GET, 3)
|
||||
return (bool(_buf[1] & 0x01), bool(_buf[1] & 0x10)) if _buf[2] == _CI_ID_END else (None, None)
|
||||
|
||||
def cmd_id(self, repeat=False):
|
||||
"""返回 识别命令词对应ID"""
|
||||
_buf = self._rreg(_CI_ID_GET, 3)
|
||||
if not repeat:
|
||||
self._wreg(bytes([_CI_ID_CLE, 0, 0, _CI_ID_END]))
|
||||
time.sleep_ms(50)
|
||||
self._cmd_id = _buf[0] if _buf[2] == _CI_ID_END else None
|
||||
return self._cmd_id
|
||||
|
||||
def result(self, ext_id=None):
|
||||
"""获取比较结果 或者输出结果"""
|
||||
return self._cmd_id if ext_id is None else bool(self._cmd_id == ext_id)
|
||||
|
||||
def sys_cmd(self, value, blocking=True):
|
||||
"""系统命令,1,2唤醒 202~205音量调整 206,207回复播报开关 208退出唤醒"""
|
||||
self.play_id(value, blocking)
|
||||
|
||||
def play_id(self, value, blocking=True):
|
||||
"""播放命令词对应ID语音"""
|
||||
self._wreg(bytes([_CI_ID_SET, value, 0, _CI_ID_END]))
|
||||
while blocking:
|
||||
time.sleep_ms(15)
|
||||
if not self.status()[1]:
|
||||
break
|
||||
|
||||
def play_num(self, value, blocking=True):
|
||||
"""播放浮点数据的合成语音"""
|
||||
self._wreg(bytes([_CI_ID_NUM]) + pack('d', float(value)) + bytes([0, _CI_ID_END]))
|
||||
while blocking:
|
||||
time.sleep_ms(10)
|
||||
if not self.status()[1]:
|
||||
break
|
||||
|
||||
def play(self, star=None, num=None, end=None, delay=10):
|
||||
"""组合播报名词+数值+单位"""
|
||||
if star is not None:
|
||||
self.play_id(star)
|
||||
time.sleep_ms(delay)
|
||||
if num is not None:
|
||||
self.play_num(num)
|
||||
time.sleep_ms(delay)
|
||||
if end is not None:
|
||||
self.play_id(end)
|
||||
time.sleep_ms(delay)
|
||||
|
||||
def play_time(self, times=None, detail=True, delay=10):
|
||||
"""播报时间"""
|
||||
data = time.localtime() if times is None else times
|
||||
if detail:
|
||||
for i in range(0, 3): #年 月 日
|
||||
self.play_num(data[i])
|
||||
time.sleep_ms(delay)
|
||||
self.play_id(_TIME_SNUM + i)
|
||||
time.sleep_ms(delay)
|
||||
|
||||
for i in range(3, 5): #时 分
|
||||
self.play_num(data[i])
|
||||
time.sleep_ms(delay)
|
||||
self.play_id(_TIME_SNUM + i)
|
||||
time.sleep_ms(delay)
|
||||
|
||||
if detail:
|
||||
self.play_num(data[5]) #秒
|
||||
time.sleep_ms(delay)
|
||||
self.play_id(_TIME_SNUM + 5)
|
||||
time.sleep_ms(delay)
|
||||
self.play_id(_TIME_SNUM + 6) #星期
|
||||
time.sleep_ms(delay)
|
||||
self.play_num(data[6] + 1)
|
||||
|
||||
def pa_ctrl(self, value=True, delay=10):
|
||||
self._wreg(bytes([_CI_ID_PACTRL, int(value), 0, _CI_ID_END]))
|
||||
if value: time.sleep_ms(delay)
|
||||
|
||||
def asr_en(self, value=None):
|
||||
if value is None:
|
||||
return self._enable
|
||||
else:
|
||||
self._enable = bool(value)
|
||||
self._wreg(bytes([_CI_ID_ASREN, self._enable, 0, _CI_ID_END]))
|
||||
166
mixly/boards/default/micropython/build/lib/debugnet.py
Normal file
166
mixly/boards/default/micropython/build/lib/debugnet.py
Normal file
@@ -0,0 +1,166 @@
|
||||
"""
|
||||
Debugnet(HTTP,MQTT)
|
||||
|
||||
MicroPython library for network request debugging
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20230225
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from umqtt import MQTTClient
|
||||
from ubinascii import hexlify
|
||||
from machine import unique_id
|
||||
from urequests import Response
|
||||
from usocket import socket,getaddrinfo,SOCK_STREAM
|
||||
from mixiot import WILL_TOPIC,ADDITIONAL_TOPIC
|
||||
|
||||
class socket_d(socket):
|
||||
def __init__(self,*args,debug=False,**kw):
|
||||
super().__init__(*args,**kw)
|
||||
self._debug=debug
|
||||
self.client_len=0
|
||||
self.server_len=0
|
||||
|
||||
def write(self,*args):
|
||||
super().write(*args)
|
||||
self.client_len=min(self.client_len+len(args[0]),65535)
|
||||
if self._debug:
|
||||
print('client:',args[0])
|
||||
|
||||
def readline(self,*args):
|
||||
buf=super().readline(*args)
|
||||
self.server_len=min(self.server_len+len(buf),65535) if buf else self.server_len
|
||||
if self._debug:
|
||||
print('server:',buf)
|
||||
return buf
|
||||
|
||||
def read(self,*args):
|
||||
buf=super().read(*args)
|
||||
self.server_len=min(self.server_len+len(buf),65535) if buf else self.server_len
|
||||
if self._debug:
|
||||
print('server:',buf)
|
||||
return buf
|
||||
|
||||
#HTTP
|
||||
def request(method, url, data=None, json=None, headers={}, stream=None, parse_headers=True, debug=False):
|
||||
redir_cnt = 1
|
||||
while True:
|
||||
try:
|
||||
proto, dummy, host, path = url.split("/", 3)
|
||||
except ValueError:
|
||||
proto, dummy, host = url.split("/", 2)
|
||||
path = ""
|
||||
if proto == "http:":
|
||||
port = 80
|
||||
elif proto == "https:":
|
||||
import ussl
|
||||
port = 443
|
||||
else:
|
||||
raise ValueError("Unsupported protocol: " + proto)
|
||||
if ":" in host:
|
||||
host, port = host.split(":", 1)
|
||||
port = int(port)
|
||||
ai = getaddrinfo(host, port, 0, SOCK_STREAM)
|
||||
ai = ai[0]
|
||||
resp_d = None
|
||||
if parse_headers is not False:
|
||||
resp_d = {}
|
||||
s = socket_d(ai[0], ai[1], ai[2], debug=debug)
|
||||
try:
|
||||
s.connect(ai[-1])
|
||||
if proto == "https:":
|
||||
s = ussl.wrap_socket(s, server_hostname=host)
|
||||
s.write(b"%s /%s HTTP/1.0\r\n" % (method, path))
|
||||
if not "Host" in headers:
|
||||
s.write(b"Host: %s\r\n" % host)
|
||||
for k in headers:
|
||||
s.write(k)
|
||||
s.write(b": ")
|
||||
s.write(headers[k])
|
||||
s.write(b"\r\n")
|
||||
if json is not None:
|
||||
assert data is None
|
||||
import ujson
|
||||
data = ujson.dumps(json)
|
||||
s.write(b"Content-Type: application/json\r\n")
|
||||
if data:
|
||||
s.write(b"Content-Length: %d\r\n" % len(data))
|
||||
s.write(b"Connection: close\r\n\r\n")
|
||||
if data:
|
||||
s.write(data)
|
||||
l = s.readline()
|
||||
l = l.split(None, 2)
|
||||
status = int(l[1])
|
||||
reason = ""
|
||||
if len(l) > 2:
|
||||
reason = l[2].rstrip()
|
||||
while True:
|
||||
l = s.readline()
|
||||
if not l or l == b"\r\n":
|
||||
break
|
||||
if l.startswith(b"Transfer-Encoding:"):
|
||||
if b"chunked" in l:
|
||||
raise ValueError("Unsupported " + l)
|
||||
elif l.startswith(b"Location:") and 300 <= status <= 399:
|
||||
if not redir_cnt:
|
||||
raise ValueError("Too many redirects")
|
||||
redir_cnt -= 1
|
||||
url = l[9:].decode().strip()
|
||||
status = 300
|
||||
break
|
||||
if parse_headers is False:
|
||||
pass
|
||||
elif parse_headers is True:
|
||||
l = l.decode()
|
||||
k, v = l.split(":", 1)
|
||||
resp_d[k] = v.strip()
|
||||
else:
|
||||
parse_headers(l, resp_d)
|
||||
except OSError:
|
||||
s.close()
|
||||
raise
|
||||
if status != 300:
|
||||
break
|
||||
resp = Response(s)
|
||||
resp.status_code = status
|
||||
resp.reason = reason
|
||||
resp.client_len=s.client_len
|
||||
resp.server_len=s.server_len
|
||||
if resp_d is not None:
|
||||
resp.headers = resp_d
|
||||
return resp
|
||||
|
||||
class MQTT_Client(MQTTClient):
|
||||
def __init__(self,*args,debug=False,**kw):
|
||||
super().__init__(*args,**kw)
|
||||
self.sock = socket_d(debug=debug)
|
||||
|
||||
@property
|
||||
def client_len(self): #The length of client data obtained
|
||||
_len=self.sock.client_len
|
||||
self.sock.client_len=0
|
||||
return _len
|
||||
|
||||
@property
|
||||
def server_len(self): #The length of server data obtained
|
||||
_len=self.sock.server_len
|
||||
self.sock.server_len=0
|
||||
return _len
|
||||
|
||||
def time_msg(self,utc=28800): #Get server time information
|
||||
msg=self.wait_msg()
|
||||
if isinstance(msg, dict):
|
||||
if msg['topic'] =='$SYS/hello':
|
||||
val=time.gmtime(int(msg['msg'])//1000-946684800+utc)[0:7]
|
||||
return str(val).replace(' ','')[1:-1]
|
||||
|
||||
#MQTT
|
||||
def init_MQTT_client(address, username, password, MQTT_USR_PRJ, debug=False):
|
||||
client = MQTT_Client(hexlify(unique_id()), address, 1883, username, password, debug=debug)
|
||||
client.set_last_will(topic=MQTT_USR_PRJ+WILL_TOPIC, msg=client.client_id, qos=2)
|
||||
if client.connect()==0:
|
||||
client.publish(MQTT_USR_PRJ+ADDITIONAL_TOPIC, client.client_id, qos=0)
|
||||
time.sleep_ms(200)
|
||||
return client
|
||||
60
mixly/boards/default/micropython/build/lib/dhtx.py
Normal file
60
mixly/boards/default/micropython/build/lib/dhtx.py
Normal file
@@ -0,0 +1,60 @@
|
||||
# DHT11/DHT22 driver for MicroPython
|
||||
# MIT license; Copyright (c) 2016 Damien P. George
|
||||
|
||||
from time import sleep
|
||||
try:
|
||||
from esp import dht_readinto
|
||||
except:
|
||||
from machine import dht_readinto
|
||||
from machine import Pin
|
||||
|
||||
class DHTBase:
|
||||
__species = {}
|
||||
__first_init = True
|
||||
def __new__(cls, pin, *args, **kwargs):
|
||||
if pin not in cls.__species.keys():
|
||||
cls.__first_init = True
|
||||
cls.__species[pin] = object.__new__(cls)
|
||||
return cls.__species[pin]
|
||||
|
||||
def __init__(self, pin):
|
||||
if self.__first_init:
|
||||
self.__first_init = False
|
||||
self.pin = Pin(pin)
|
||||
self.buf = bytearray(5)
|
||||
self.err = 0
|
||||
|
||||
def measure(self):
|
||||
buf = bytearray(5)
|
||||
try:
|
||||
dht_readinto(self.pin, buf)
|
||||
if (buf[0] + buf[1] + buf[2] + buf[3]) & 0xFF == buf[4]:
|
||||
self.buf = buf
|
||||
self.err = 0
|
||||
except:
|
||||
if self.err > 10:
|
||||
raise AttributeError("DHTx operation error")
|
||||
self.err += 1
|
||||
sleep(0.5)
|
||||
return
|
||||
|
||||
class DHT11(DHTBase):
|
||||
def humidity(self):
|
||||
self.measure()
|
||||
return self.buf[0]
|
||||
|
||||
def temperature(self):
|
||||
self.measure()
|
||||
return self.buf[2]
|
||||
|
||||
class DHT22(DHTBase):
|
||||
def humidity(self):
|
||||
self.measure()
|
||||
return (self.buf[0] << 8 | self.buf[1]) * 0.1
|
||||
|
||||
def temperature(self):
|
||||
self.measure()
|
||||
t = ((self.buf[2] & 0x7F) << 8 | self.buf[3]) * 0.1
|
||||
if self.buf[2] & 0x80:
|
||||
t = -t
|
||||
return t
|
||||
67
mixly/boards/default/micropython/build/lib/ds18b20.py
Normal file
67
mixly/boards/default/micropython/build/lib/ds18b20.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# DS18x20 temperature sensor driver for MicroPython.
|
||||
# MIT license; Copyright (c) 2016 Damien P. George
|
||||
|
||||
import onewire
|
||||
from machine import Pin
|
||||
from micropython import const
|
||||
|
||||
_CONVERT = const(0x44)
|
||||
_RD_SCRATCH = const(0xBE)
|
||||
_WR_SCRATCH = const(0x4E)
|
||||
|
||||
class DS18X20:
|
||||
__species = {}
|
||||
__first_init = True
|
||||
def __new__(cls, pin, *args, **kwargs):
|
||||
if pin not in cls.__species.keys():
|
||||
cls.__first_init = True
|
||||
cls.__species[pin] = object.__new__(cls)
|
||||
return cls.__species[pin]
|
||||
|
||||
def __init__(self, pin):
|
||||
if self.__first_init:
|
||||
self.__first_init = False
|
||||
self._ow = onewire.OneWire(Pin(pin, pull=Pin.PULL_UP))
|
||||
self._buf = bytearray(9)
|
||||
self._roms = self.scan()
|
||||
if len(self._roms) == 0:
|
||||
raise AttributeError("Cannot find a DS18X20")
|
||||
|
||||
def scan(self):
|
||||
return [rom for rom in self._ow.scan() if rom[0] in (0x10, 0x22, 0x28)]
|
||||
|
||||
def convert_temp(self):
|
||||
self._ow.reset(True)
|
||||
self._ow.writebyte(self._ow.SKIP_ROM)
|
||||
self._ow.writebyte(_CONVERT)
|
||||
|
||||
def read_scratch(self, rom):
|
||||
self._ow.reset(True)
|
||||
self._ow.select_rom(rom)
|
||||
self._ow.writebyte(_RD_SCRATCH)
|
||||
self._ow.readinto(self._buf)
|
||||
if self._ow.crc8(self._buf):
|
||||
raise Exception("CRC error")
|
||||
return self._buf
|
||||
|
||||
def read_temp(self, rom):
|
||||
buf = self.read_scratch(rom)
|
||||
if rom[0] == 0x10:
|
||||
if buf[1]:
|
||||
t = buf[0] >> 1 | 0x80
|
||||
t = -((~t + 1) & 0xFF)
|
||||
else:
|
||||
t = buf[0] >> 1
|
||||
return t - 0.25 + (buf[7] - buf[6]) / buf[7]
|
||||
else:
|
||||
t = buf[1] << 8 | buf[0]
|
||||
if t & 0x8000: # sign bit set
|
||||
t = -((t ^ 0xFFFF) + 1)
|
||||
return t / 16
|
||||
|
||||
def temperature(self):
|
||||
temp = []
|
||||
self.convert_temp()
|
||||
for rom in self._roms:
|
||||
temp.append(round(self.read_temp(rom), 2))
|
||||
return temp [0] if len(temp) == 1 else tuple(temp)
|
||||
@@ -0,0 +1,21 @@
|
||||
#Take the picture bytes in expression_picture.py
|
||||
#--dahanzimin From the Mixly Team
|
||||
|
||||
Angry=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x7f\xff\xff\xfc\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x03\xff\xfd\x7f\xff\xc0\x00\x00\x07\xff\x80\x01\xff\xe0\x00\x00\x0f\xfc\x00\x00\x7f\xf0\x00\x00\x1f\xf8\x00\x00\x1f\xf8\x00\x00?\xe0\x00\x01\x87\xfc\x00\x00\x7f\x80\x00\x01\xd9\xfe\x00\x00\xff\x00\x00\x07\xfc\xff\x00\x01\xfe\x00\x00\x07\xfe\x7f\x80\x01\xfc\x00\x00\x03\x1c?\x80\x03\xf8\x00\x00\x0f\x18\x1f\xc0\x03\xf0\x00\x00\x0e\xdc\x0f\xc0\x07\xf0\x00\x00\x07\xfc\x0f\xe0\x07\xe0\x00\x00\x07\xf8\x07\xe0\x0f\xc0\x00\x00\x02`\x03\xf0\x0f\xc0\x00\x00\x00 \x03\xf0\x1f\xc0\x00\x00\x00\x00\x03\xf8\x1f\x83\x00\x00\x00\x00\xc1\xf8\x1f\x83\xc0\x00\x00\x03\xc1\xf8\x1f\x03\xf0\x00\x00\x1f\xc1\xf8?\x07\xfe\x00\x00?\xe0\xfc?\x03\xff\x80\x01\xff\xc0\xfc?\x03\xff\xe0\x07\xff\xc0\xfc?\x03\xff\xe0\x03\xff\x80\xfc?\x01\xff\xc0\x03\xff\x80|?\x00\xff\x80\x01\xff\x00\xfc>\x00>\x00\x00|\x00|?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc\x1f\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x0f\xc0\x00\x00\x00\x00\x01\xf8\x1f\xc0\x00\x00\x00\x00\x03\xf0\x0f\xc0\x00\x00\x00\x00\x07\xf0\x07\xe0\x00\x03\x80\x00\x07\xe0\x07\xf0\x00\x07\xc0\x00\x0f\xe0\x03\xf0\x00\x0f\xf0\x00\x0f\xc0\x03\xf8\x00\x1e\xf8\x00\x1f\xc0\x01\xfc\x00\x1c~\x00?\x80\x01\xfe\x00\x00\x1c\x00\x7f\x80\x00\xff\x00\x00\x04\x00\xff\x00\x00\x7f\xc0\x00\x00\x01\xfe\x00\x00?\xe0\x00\x00\x07\xfc\x00\x00\x1f\xf8\x00\x00\x1f\xf8\x00\x00\x0f\xfe\x00\x00\x7f\xf0\x00\x00\x07\xff\xc0\x05\xff\xe0\x00\x00\x01\xff\xff\xff\xff\x80\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Bored=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x7f\xff\xff\xfc\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x03\xff\xfd\x7f\xff\xc0\x00\x00\x07\xff\x80\x01\xff\xe0\x00\x00\x0f\xfc\x00\x00\x7f\xf0\x00\x00\x1f\xf8\x00\x00\x1f\xf8\x00\x00?\xc0\x00\x00\x07\xfc\x00\x00\x7f\xc0\x00\x00\x01\xfe\x00\x00\xff\x00\x00\x00\x00\xff\x00\x01\xfe\x00\x00\x00\x00\x7f\x00\x01\xfc\x00\x00\x00\x00?\x80\x03\xf8\x00\x00\x00\x00\x1f\xc0\x03\xf0\x00\x00\x00\x00\x0f\xc0\x07\xf0\x00\x00\x00\x00\x0f\xe0\x07\xe0\x00\x00\x00\x00\x07\xf0\x0f\xe0\x00\x00\x00\x00\x07\xf0\x0f\xc0\x00\x00\x00\x00\x03\xf0\x1f\x80\x00\x00\x00\x00\x03\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\x83[\x00\x00\xdfA\xf8\x1f\x87\xff\x80\x01\xff\xe0\xf8?\x07\xff\x00\x01\xff\xe0\xfc?\x01}\x00\x00\x8e\x00\xfc?\x000\x00\x00\x0e\x00\xfc?\x00p\x00\x00\x1c\x00\xfc>\x05~\x80\x00_\xc0|?\x07\xff\x80\x01\xff\xe0\xfc?\x07\xff\x80\x01\xff\xe0\xfc>\x02D\x00\x00\xa4\x80|?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc\x1f\x00\x00\x00\x00\x00\x00\xfc?\x80\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x0f\xc0\x00\x00\x00\x00\x01\xf8\x0f\xc0\x00\x07\xf0\x00\x03\xf0\x0f\xe0\x00\x1f\xfc\x00\x07\xf0\x07\xe0\x00?\xfe\x00\x07\xe0\x07\xf0\x00|\x1f\x00\x07\xe0\x03\xf8\x00p\x07\x00\x1f\xc0\x03\xf8\x00\xe0\x07\x80\x1f\xc0\x01\xfc\x00s\xe3\x80?\x80\x00\xfe\x00c\xf3\x00\x7f\x00\x00\xff\x00\x03\xe0\x00\xff\x00\x00\x7f\xc0\x00\x00\x01\xfe\x00\x00?\xe0\x00\x00\x07\xfc\x00\x00\x1f\xf0\x00\x00\x1f\xf8\x00\x00\x0f\xfe\x00\x00\x7f\xf0\x00\x00\x07\xff\xc0\x01\xff\xe0\x00\x00\x03\xff\xfa\xbf\xff\x80\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xfe\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x01\xff\xff\xc0\x00\x00\x00\x00\x00_\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Confused=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x7f\xff\xff\xfc\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x03\xff\xfd\x7f\xff\xc0\x00\x00\x07\xff\x80\x01\xff\xe0\x00\x00\x0f\xfc\x00\x00\x7f\xf0\x00\x00\x1f\xf8\x00\x00\x1f\xf8\x00\x00?\xc0\x00\x00\x07\xfc\x00\x00\x7f\xc0\x00\x00\x01\xfe\x00\x00\xff\x00\x00\x00\x00\xff\x00\x01\xfe\x00\x00\x00\x00\x7f\x00\x01\xfc\x00\x00\x00\x00?\x80\x03\xf8\x06\x00\x00\x00\x1f\xc0\x03\xf0\x0f\x00\x01\xfc\x1f\xc0\x07\xf0\x1f\x00\x01\xff\x0f\xe0\x07\xe0?\x00\x01\xff\x87\xe0\x0f\xc0~\x00\x00\xff\xc7\xf0\x0f\xdf\xfc\x00\x00\x07\xe3\xf0\x1f\xdf\xf8\x00\x00\x01\xf3\xf8\x1f\x9f\xe0\x00\x00\x00\xf1\xf8\x1f\x8f(\x00\x00\x18\xe1\xf8\x1f\x00~\x00\x00~!\xf8?\x00\xff\x00\x00\xfe\x00\xfc?\x00\xff\x80\x00\xff\x00\xfc?\x00\xff\x80\x01\xff\x00\xfc?\x00\xff\x00\x01\xff\x00\xfc?\x00\xff\x80\x00\xff\x00\xfc?\x00~\x00\x00\xfe\x00\xfc>\x00>\x00\x00|\x00|?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc\x1f\x00\x00\x00\x00\x00\x00\xf8?\x80\x00\x00\x00\x00\x01\xfc\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x0f\xc0\x00\x00\x00\x00\x01\xf8\x0f\xc0\x00\x00\x00\x00\x03\xf0\x0f\xe0\x00\x00\x00\x00\x03\xf0\x07\xe0\x00\x00\x00\x00\x07\xe0\x07\xf0\x00\x1f\x80\x00\x0f\xe0\x03\xf0\x00?\xc0\x00\x0f\xc0\x03\xf8\x00?\xc7\x00\x1f\xc0\x01\xfc\x009\xe7\x00?\x80\x00\xfe\x001\xe7\x00\x7f\x80\x00\xff\x000\xfe\x00\xff\x00\x00\x7f\xc0\x00~\x03\xfe\x00\x00?\xe0\x00<\x07\xfc\x00\x00\x1f\xf8\x00\x00\x1f\xf8\x00\x00\x0f\xfe\x00\x00\x7f\xf0\x00\x00\x07\xff\xc0\x01\xff\xe0\x00\x00\x03\xff\xff\xff\xff\x80\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00?\xfe\xff\xfc\x00\x00\x00\x00\x0f\xff\xff\xf8\x00\x00\x00\x00\x01\xff\xff\x80\x00\x00\x00\x00\x00?\xfa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Happy=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x03\xff\xff\x7f\xff\xc0\x00\x00\x07\xff\x80\x03\xff\xe0\x00\x00\x0f\xfc\x00\x00?\xf0\x00\x00\x1f\xf0\x00\x00\x1f\xf8\x00\x00?\xe0\x00\x00\x07\xfc\x00\x00\x7f\x80\x00\x00\x01\xfe\x00\x00\xff\x00\x00\x00\x00\xff\x00\x00\xfe\x00\x00\x00\x00\x7f\x00\x03\xfc\x00\x00\x00\x00?\x80\x03\xf8\x00\x00\x00\x00\x1f\xc0\x03\xf8\x00\x00\x00\x00\x0f\xc0\x07\xe0\x00\x00\x00\x00\x0f\xe0\x07\xe0\x00\x00\x00\x00\x07\xf0\x0f\xe0\x00\x00\x00\x00\x07\xf0\x0f\xc0\x00\x00\x00\x00\x03\xf0\x1f\xc0\x00\x00\x00\x00\x03\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\x80\x14\x00\x008\x01\xf8\x1f\x00~\x00\x00~\x00\xf8?\x00\xff\x00\x00\xff\x00\xfc?\x00\xff\x80\x01\xff\x00\xfc?\x00\xff\x00\x01\xff\x00\xfc?\x00\xff\x80\x00\xff\x00\xfc?\x00\xff\x00\x00\xff\x00\xfc?\x00\x7f\x00\x00\xfe\x00|>\x00<\x00\x00|\x00\xfc?\x00\x00\x00\x00\x00\x00|?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc\x1f\x00\x00\x00\x00\x00\x00\xf8?\x80\x00\x00\x00\x00\x01\xfc\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\xc0\x00\x00\x00\x00\x01\xf8\x0f\xc0\x00\x00\x00\x00\x03\xf0\x0f\xe0\x02\xfa\xd5\x80\x07\xf0\x07\xe0\x03\xff\xff\xc0\x07\xe0\x07\xf0\x07\xff\xff\xe0\x0f\xe0\x03\xf8\x03\xff\xff\xc0\x0f\xc0\x03\xf8\x03\xff\xff\xc0\x1f\xc0\x01\xfc\x01\xff\xff\x80?\x80\x01\xfe\x01\xff\xff\x80\x7f\x80\x00\xff\x00\xff\xff\x00\xff\x00\x00\x7f\x80\x7f\xfe\x03\xfe\x00\x00?\xe0?\xfc\x07\xfc\x00\x00\x1f\xf0\x07\xf0\x1f\xf8\x00\x00\x0f\xfe\x00\x00\x7f\xf0\x00\x00\x07\xff\xc0\x01\xff\xe0\x00\x00\x03\xff\xfe\xbf\xff\x80\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x01\xff\xff\xc0\x00\x00\x00\x00\x00?\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Heart=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfe\x00\x00\x7f\xc0\x00\x00\x1f\xff\xc0\x03\xff\xf8\x00\x00\x7f\xff\xf0\x0f\xff\xfe\x00\x00\xff\xff\xf8\x1f\xff\xff\x00\x01\xff\xff\xfe\x7f\xff\xff\x80\x03\xff\xff\xff\x7f\xff\xff\xc0\x07\xff\xff\xff\xff\xff\xff\xe0\x0f\xff\xff\xff\xff\xff\xff\xf0\x0f\xff\xff\xff\xff\xff\xff\xf0\x1f\xff\xff\xff\xff\xff\xff\xf8\x1f\xff\xff\xff\xff\xff\xff\xf8\x1f\xff\xff\xff\xff\xff\xff\xf8?\xff\xff\xff\xff\xff\xff\xfc?\xff\xff\xff\xff\xff\xff\xfc?\xff\xff\xff\xff\xff\xff\xfc?\xff\xff\xff\xff\xff\xff\xfc?\xff\xff\xff\xff\xff\xff\xfc?\xff\xff\xff\xff\xff\xff\xfc?\xff\xff\xff\xff\xff\xff\xfc?\xff\xff\xff\xff\xff\xff\xfc?\xff\xff\xff\xff\xff\xff\xf8\x1f\xff\xff\xff\xff\xff\xff\xfc\x1f\xff\xff\xff\xff\xff\xff\xf8\x1f\xff\xff\xff\xff\xff\xff\xf8\x0f\xff\xff\xff\xff\xff\xff\xf0\x0f\xff\xff\xff\xff\xff\xff\xf0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xc0\x03\xff\xff\xff\xff\xff\xff\xc0\x01\xff\xff\xff\xff\xff\xff\x80\x00\xff\xff\xff\xff\xff\xff\x80\x00\xff\xff\xff\xff\xff\xff\x00\x00\x7f\xff\xff\xff\xff\xfe\x00\x00?\xff\xff\xff\xff\xfc\x00\x00\x1f\xff\xff\xff\xff\xf8\x00\x00\x0f\xff\xff\xff\xff\xf0\x00\x00\x07\xff\xff\xff\xff\xe0\x00\x00\x03\xff\xff\xff\xff\xc0\x00\x00\x01\xff\xff\xff\xff\xc0\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x7f\xff\xff\xfe\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\x1f\xff\xff\xf8\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x07\xff\xff\xe0\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x01\xff\xff\x80\x00\x00\x00\x00\x00\xff\xfe\x00\x00\x00\x00\x00\x00?\xfe\x00\x00\x00\x00\x00\x00\x1f\xf8\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x07\xe0\x00\x00\x00\x00\x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Paper=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\x00\x00\x00\x00\x00\x00\x01\xff\x00`\x00\x00\x00\x00\x01\xff\x83\xfc\x00\x00\x00\x00\x07\xff\xc7\xff\x00\x00\x00\x00\x07\xe7\xcf\xff\x80\x00\x00\x00\x0f\x83\xff\xff\x80\x00\x00\x00\x0f\x03\xff\x07\x80\x00\x00\x00\x0f\x03\xfe\x07\xc0\x00\x00\x00\x1f\x01\xfc\x03\xc0\x00\x00\x00\x1e\x01\xf8\x03\xc0\x00\x00\x00\x1e\x01\xf8\x07\xcc\x00\x00\x00\x1e\x03\xf0\x07\xff\x00\x00\x00\x1e\x03\xe0\x0f\xff\x80\x00\xbc\x1e\x03\xe0\x0f\xff\xc0\x01\xff\x1e\x03\xc0\x1f\xff\xc0\x03\xff\xfe\x03\xc0?\xc3\xe0\x07\xff\xfe\x01\xc0?\x81\xe0\x07\xc7\xfe\x00\x00~\x01\xe0\x07\x81\xfe\x00\x00\xfc\x01\xe0\x0f\x80\xfe\x00\x01\xf8\x03\xe0\x0f\x80~\x00\x01\xf0\x07\xc0\x07\x80>\x00\x00\xe0\x0f\xc0\x07\x80\x1e\x00\x00@\x1f\x80\x07\xc0\x0e\x00\x00\x00?\x00\x03\xe0\x06\x00\x00\x00~\x00\x03\xe0\x06\x00\x00\x00\xfc\x00\x01\xf0\x02\x00\x00\x03\xff\x00\x00\xf8\x00\x00\x00\x07\xff\xc0\x00\xfc\x00\x00\x00\x07\xff\xe0\x00|\x00\x00\x00\x07\xff\xe0\x00>\x00\x00\x00\x03\x81\xf0\x00\x1e\x00\x00\x00\x00\x00\xf0\x00\x1e\x00\x00\x00\x00\x00\xf0\x00\x1e\x00\x00\x00\x00\x01\xf0\x00\x1e\x00\x00\x00\x00\x03\xf0\x00\x1e\x00\x00\x00\x00\x07\xe0\x00>\x00\x00\x00\x00\x7f\xc0\x00<\x00\x00\x00\xff\xff\x80\x00|\x00\x00\x01\xff\xff\x00\x00|\x00\x00\x03\xff\xfc\x00\x00<\x00\x00\x03\xff\xe0\x00\x00<\x00\x00\x07\xe0\x00\x00\x00>\x00\x00\x0f\x80\x00\x00\x00>\x00\x00\x1f\x80\x00\x00\x00\x1f\x00\x00?\x00\x00\x00\x00\x0f\x80\x00~\x00\x00\x00\x00\x0f\xc0\x00\xfc\x00\x00\x00\x00\x07\xf0\x03\xf8\x00\x00\x00\x00\x03\xf8\x07\xf0\x00\x00\x00\x00\x01\xff?\xc0\x00\x00\x00\x00\x00\x7f\xff\x80\x00\x00\x00\x00\x00?\xff\x00\x00\x00\x00\x00\x00\x0f\xfc\x00\x00\x00\x00\x00\x00\x03\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Rock=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00\x00\xc1\xff\xc0\x00\x00\x00\x00\x07\xff\xff\xe0\x00\x00\x00\x00\x1f\xff\xff\xf0\x00\x00\x00\x00?\xff\xc3\xf8\x00\x00\x00\x00?\xff\x00\xff\xf0\x00\x00\x00|\x0f\x00\x7f\xfc\x00\x00\x00x\x0e\x00\xff\xfe\x00\x00\x07\xf8\x1e\x03\xff\xff\x00\x00\x1f\xf8\x1c\x0f\xf0\x1f\x80\x00?\xf0\x1c\x1f\x80\x0f\xc0\x00\x7f\xf0\x1c\x1e\x00\x07\xe0\x00\xfe\xf0\x1e<\x00\x03\xe0\x00\xf8p\x1e8\x00\x01\xe0\x00\xf0p\x0e8\x00\x01\xf0\x01\xf0x\x0e8\x00\x00\xf0\x01\xe0x\x0f8\x00\x00\xf0\x01\xe0<\x078\x00\x00\xf0\x01\xe0<\x07\xfc\x0f\x00\xf0\x03\xe0\x1e\x03\xbf\xff\x00\xf0\x0f\xf0\x1f\x03\xff\xff\x00\xf8\x1f\xf0\x0f\x81\xef\xfc\x00\xf8\x1f\xf0\x07\xc0\xff\xe0\x00x>x\x03\xe0\xff\x80\x00\xf8><\x01\xf1\xfc\x00\x00\xf8<>\x00\xff\xf0\x00\x00\xf8<\x1f\x00\x7f\xc0\x00\x00\xf0<\x0f\x80?\x00\x00\x00\xf0>\x07\xc0~\x00\x00\x00\xf0\x1e\x03\xe1\xf8\x00\x00\x00\xf0\x1f\x01\xf3\xf0\x00\x00\x01\xf0\x1f\x00\xff\xc0\x00\x00\x01\xe0\x0f\x80\x7f\x80\x00\x00\x01\xe0\x0f\x80\x1f\x00\x00\x00\x03\xe0\x07\xc0\x1e\x00\x00\x00\x03\xe0\x03\xe0<\x00\x00\x00\x07\xc0\x03\xf8x\x00\x00\x00\x0f\xc0\x01\xfcx\x00\x00\x00\x1f\x80\x00\xff\xf0\x00\x00\x00\x7f\x00\x00?\xf0\x00\x00\x01\xfe\x00\x00\x1f\xf0\x00\x00\x07\xfc\x00\x00\x07\xf0\x00\x00\x1f\xf0\x00\x00\x00\xf8\x00\x00?\xc0\x00\x00\x00|\x00\x00\xff\x80\x00\x00\x00~\x00\x03\xfe\x00\x00\x00\x00?\x00\x0f\xf8\x00\x00\x00\x00\x1f\x80?\xe0\x00\x00\x00\x00\x1f\xe0\xff\x80\x00\x00\x00\x00\x07\xff\xfe\x00\x00\x00\x00\x00\x03\xff\xf8\x00\x00\x00\x00\x00\x01\xff\xe0\x00\x00\x00\x00\x00\x00\x7f\xc0\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Sad=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x03\xff\xfe\xff\xff\xc0\x00\x00\x07\xff\x80\x03\xff\xe0\x00\x00\x0f\xfe\x00\x00\x7f\xf0\x00\x00\x1f\xf0\x00\x00\x1f\xf8\x00\x00?\xe0\x00\x00\x07\xfc\x00\x00\x7f\x80\x00\x00\x01\xfe\x00\x00\xff\x00\x00\x00\x00\xff\x00\x01\xfe\x00\x00\x00\x00\x7f\x00\x01\xfc\x00\x00\x00\x00?\x80\x03\xf8\x00\x00\x00\x00\x1f\xc0\x03\xf0\x00\x00\x00\x00\x1f\xc0\x07\xf0\x00\x00\x00\x00\x0f\xe0\x0f\xe0\x00\x00\x00\x00\x07\xe0\x07\xe0\x00\x00\x00\x00\x07\xf0\x0f\xc0\x00\x00\x00\x00\x03\xf0\x1f\xc0\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8?\x00\x00\x00\x00\x00\x01\xfc\x1f\x07\xff\xe0\x0f\xff\xc0\xf8?\x07\xff\xe0\x0f\xff\xe0\xfc?\x07\xff\xf0\x0f\xff\xc0\xfc?\x07\xff\xe0\x0f\xff\xc0\xfc?\x00\x7f\x00\x00\xfe\x00\xfc?\x00?\x00\x00\xfc\x00\xfc>\x00\x7f\x00\x00\xfe\x00|?\x00?\x00\x00~\x00\xfc?\x00~\x00\x00\xfe\x00\xfc?\x00?\x00\x00\xfe\x00\xfc?\x00\x7f\x00\x00\xfc\x00\xfc\x1f\x00\x7f\x00\x00\xfe\x00\xf8\x1f\x00?\x00\x00\xfe\x01\xfc\x1f\x80\x7f\x00\x00\xfe\x01\xf8\x1f\x80\x7f\x00\x00\xfe\x01\xf8\x1f\xc0?\x00\x00|\x01\xf8\x0f\xc0\x7f\x00\x00\xfe\x03\xf0\x0f\xe0\x7f\x0f\xe0\xfe\x03\xf0\x07\xe0?\x1f\xf8\xfe\x07\xe0\x07\xf0\x7f\x7f\xfe\xfc\x0f\xe0\x03\xf0\x7f|?~\x0f\xc0\x03\xf8?\xf0\x0f\xfe\x1f\xc0\x01\xfc\x7f\xe0\x07\xfe?\x80\x00\xfe\x7f\xc0\x03\xfe\x7f\x00\x00\xff?@\x02\xfe\xff\x00\x00\x7f\xff\x00\x00\xff\xfe\x00\x00?\xff\x00\x00\xff\xfc\x00\x00\x1f\xff\x00\x00\xff\xf8\x00\x00\x0f\xff\x00\x00\xff\xf0\x00\x00\x07\xff\xc0\x00\xff\xe0\x00\x00\x01\xff\xff\x7f\xff\x80\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\x0f\xff\xff\xf8\x00\x00\x00\x00\x03\xff\xff\x80\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Scissors=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x80\x00\x00\x00\x00\x00\x00?\xf0\x00\x00\x00\x00\x00\x00\xff\xfc\x00\x00\x00\x00\x00\x01\xff\xff\x00\x00\x00\x00\x00\x01\xf8\xff\x80\x00\x00\x00\x00\x03\xe0\x1f\xc0\x00\x00\x00\x00\x07\xc0\x07\xf0\x00\x00\x00\x00\x07\xc0\x03\xf8\x00\x00\x00\x00\x07\x80\x01\xfc\x00\x00\x00\x00\x07\x80\x00~\x00\x00\x00\x00\x07\x80\x00?\x00\x00\x00\x00\x07\x80\x00\x1f\xfc\x00\x00\x00\x07\xc0\x00\x0f\xff\x80\x00\x00\x03\xe0\x00\x07\xff\xe0\x00\x00\x03\xf0\x00\x03\xff\xf8\x00\x00\x01\xf8\x00\x00\xe7\xfc\x00\x00\x00\xfc\x00\x01\xe0\xfe\x00\x00\x00\x7f\x00\x01\xe0?\x00\x00\x03\xff\x80\x01\xc0\x1f\x80\x00\x7f\xff\xe0\x03\xc0\x1f\x80\x01\xff\xff\xf8\x03\x80\x1f\xc0\x03\xff\xff\xff\x03\x80\x1f\xe0\x07\xff\xff\xff\x07\x80\x1f\xe0\x0f\xc0\x01\xff\x07\x00\x1f\xe0\x0f\x80\x00\x1e\x07\x00=\xf0\x1f\x00\x00\x00\x07\x00<\xf0\x1e\x00\x00\x00\x07\x008\xf0\x1e\x00\x00\x00\x0f\x00x\xf0\x1e\x00\x00\x00\x7f\x00\xf0\xf0\x1f\x00\x00\x01\xff\x00\xf0\xf8\x0f\x00\x00\x07\xff\x01\xe0\xf8\x0f\x80\x00\x0f\xef\x03\xc0x\x0f\xe0\x00?\x07\x87\xc0\xf8\x07\xff\x7f\xfe\x03\xff\x80\xf8\x03\xff\xff\xfc\x03\xff\x00\xf8\x01\xff\xff\xf8\x01\xfe\x00\xf0\x00\x7f\xff\xf8\x07\xff\x00\xf0\x00\x01\xd0|\x7f\xff\xc0\xf0\x00\x00\x00\x7f\xff\xff\xe0\xf0\x00\x00\x00?\xfc\x01\xf1\xf0\x00\x00\x00\x1f\xe0\x00\xf1\xe0\x00\x00\x00\x0f\x00\x00s\xe0\x00\x00\x00\x0f\x00\x00s\xe0\x00\x00\x00\x0f\x00\x00\xff\xc0\x00\x00\x00\x0f\x00\x00\xff\x80\x00\x00\x00\x0f\x80\x03\xff\x00\x00\x00\x00\x07\xf0\xff\xfe\x00\x00\x00\x00\x07\xff\xff\xfc\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x01\xff\xfe\x00\x00\x00\x00\x00\x007@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Silly=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x03\xff\xf4\x1f\xff\xc0\x00\x00\x07\xff\x00\x01\xff\xe0\x00\x00\x0f\xfc\x00\x00?\xf0\x00\x00\x1f\xf0\x00\x00\x0f\xf8\x00\x00?\xc0\x00\x00\x03\xfc\x00\x00\x7f\x80\x00\x00\x01\xfe\x00\x00\xff\x00\x00\x00\x00\xff\x00\x00\xfc\x00\x00\x00\x00?\x00\x01\xfc\x00\x00\x00\x00?\x80\x03\xf8\x00\x00\x00\x00\x1f\xc0\x07\xf0\x01\x00\x00\x00\x0f\xc0\x07\xe0\x03\x80\x01\xe0\x07\xe0\x07\xe0\x07\x80\x01\xe0\x07\xe0\x0f\xc0\x0f\x80\x01\xf0\x03\xf0\x0f\xc0?\x00\x00\xfc\x03\xf0\x1f\x87\xfe\x00\x00\x7f\xe1\xf8\x1f\x87\xfc\x00\x00?\xe1\xf8\x1f\x07\xf8\x00\x00\x0f\xf0\xf8\x1f\x07\xcc\x00\x00s\xe1\xf8?\x00\x1f\x00\x00\xf8\x00\xfc?\x00?\x80\x01\xfc\x00\xfc?\x00\x7f\xc0\x03\xfc\x00|>\x00\x7f\xc0\x01\xfe\x00\xfc>\x00?\x80\x03\xfe\x00|>\x00?\x80\x01\xfc\x00|?\x00?\x80\x00\xf8\x00|>\x00\x0e\x00\x00p\x00\xfc>\x00\x00\x00\x00\x00\x00|?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc\x1f\x00\x00\x03\xc0\x00\x00\xf8?\x00\x00\x07\xe0\x00\x00\xfc\x1f\x00\x00\x0f\xe0\x00\x00\xf8\x1f\x80\x00\x07\xe0\x00\x01\xf8\x1f\x80\x00\x07\xf0\x00\x01\xf8\x0f\xc0\x00\x0f\xe0\x00\x03\xf0\x0f\xc0\x00\x0f\xe0\x00\x03\xf0\x07\xe0\x00\x07\xe0\x00\x07\xe0\x07\xe0\x00\x07\xf0\x00\x07\xe0\x07\xf0\x00\x0f\xe0\x00\x0f\xc0\x03\xf8\x00\x07\xe0\x00\x1f\xc0\x01\xfc\x00\x0f\xf0\x00?\x80\x00\xfc\x00\x07\xe0\x00?\x00\x00\xff\x00\x07\xe0\x00\xff\x00\x00\x7f\x80\x07\xc0\x01\xfe\x00\x00?\xc0\x00\x80\x03\xfc\x00\x00\x1f\xf0\x00\x00\x0f\xf8\x00\x00\x0f\xfc\x00\x00?\xf0\x00\x00\x07\xff\x00\x01\xff\xe0\x00\x00\x01\xff\xfa7\xff\x80\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x00?\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Sleep=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x7f\xff\xff\xfc\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x03\xff\xfd\x7f\xff\xc0\x00\x00\x07\xff\x80\x01\xff\xe0\x00\x00\x0f\xfc\x00\x00\x7f\xf0\x00\x00\x1f\xf8\x00\x00\x1f\xf8\x00\x00?\xc0\x00\x00\x07\xfc\x00\x00\x7f\xc0\x00\x00\x01\xfe\x00\x00\xff\x00\x00\x00\x00\xff\x00\x01\xfe\x00\x00\x00\x00\x7f\x00\x01\xfc\x00\x00\x00\x00?\x80\x03\xf8\x00\x00\x00\x03\xff\xc0\x03\xf0\x00\x00\x00\x07\xef\xc0\x07\xf0\x00\x00\x00\x00\xef\xe0\x07\xe0\x00\x00\x00\x01\xc7\xe0\x0f\xe0\x00\x00\x00\x07\xa7\xf0\x0f\xc0\x00\x00\x00\x07\xe3\xf0\x1f\x80\x00\x00\x00\xf3C\xf8\x1f\x80\x00\x00\x01\xf8\x01\xf8\x1f\x80\x00\x00\x00p\x01\xf8\x1f\x80\x00\x00\x00\xe0\x00\xf8?\x00\x00\x00\x01\xf8\x00\xfc?\x00\x00\x00\x00\xf0\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc>\x03\xff\xe0\x07\xaf\xc0\xfc?\x03\xff\xe0\x07\xff\xc0\xfc?\x03\xff\xe0\x07\xff\xc0|?\x01\xff\x80\x03\xff\x80\xfc>\x00\x00\x00\x00\x10\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc\x1f\x00\x00\x00\x00\x00\x00\xfc?\x80\x00\x00\x00\x00\x00\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x01@\x00\x01\xf8\x1f\xc0\x00\x1f\xf8\x00\x03\xf8\x0f\xc0\x00\x7f\xfe\x00\x03\xf0\x0f\xe0\x00\xff\xff\x00\x03\xf0\x07\xe0\x01\xff\xff\x80\x07\xe0\x07\xf0\x01\xff\xff\x80\x0f\xe0\x03\xf0\x03\xff\xff\xc0\x0f\xc0\x03\xf8\x03\xff\xff\xc0?\xc0\x01\xfc\x01\xff\xff\x80?\x80\x00\xfe\x01\xff\xff\x80\x7f\x80\x00\xff\x00|\x00\x00\xff\x00\x00\x7f\x80x\x00\x01\xfe\x00\x00?\xe0<\x00\x07\xfc\x00\x00\x1f\xf88\x00\x1f\xf8\x00\x00\x0f\xfe\x00\x00\x7f\xf0\x00\x00\x07\xff\x80\x03\xff\xe0\x00\x00\x03\xff\xfd\xff\xff\x80\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\x0f\xff\xff\xf8\x00\x00\x00\x00\x03\xff\xff\x80\x00\x00\x00\x00\x00?\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Small_heart=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xe0\x07\xf8\x00\x00\x00\x00\x7f\xf8\x1f\xfe\x00\x00\x00\x00\xff\xfe?\xff\x00\x00\x00\x01\xff\xff\x7f\xff\x80\x00\x00\x03\xff\xff\xff\xff\xc0\x00\x00\x07\xff\xff\xff\xff\xe0\x00\x00\x07\xff\xff\xff\xff\xe0\x00\x00\x0f\xff\xff\xff\xff\xf0\x00\x00\x0f\xff\xff\xff\xff\xf0\x00\x00\x0f\xff\xff\xff\xff\xf0\x00\x00\x0f\xff\xff\xff\xff\xf0\x00\x00\x0f\xff\xff\xff\xff\xf0\x00\x00\x0f\xff\xff\xff\xff\xf0\x00\x00\x0f\xff\xff\xff\xff\xf0\x00\x00\x0f\xff\xff\xff\xff\xe0\x00\x00\x07\xff\xff\xff\xff\xe0\x00\x00\x07\xff\xff\xff\xff\xe0\x00\x00\x03\xff\xff\xff\xff\xc0\x00\x00\x03\xff\xff\xff\xff\xc0\x00\x00\x01\xff\xff\xff\xff\x80\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x7f\xff\xff\xff\x00\x00\x00\x00\x7f\xff\xff\xfc\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\x1f\xff\xff\xf8\x00\x00\x00\x00\x0f\xff\xff\xe0\x00\x00\x00\x00\x07\xff\xff\xe0\x00\x00\x00\x00\x01\xff\xff\xc0\x00\x00\x00\x00\x01\xff\xff\x00\x00\x00\x00\x00\x00\x7f\xff\x00\x00\x00\x00\x00\x00\x7f\xfc\x00\x00\x00\x00\x00\x00\x1f\xf8\x00\x00\x00\x00\x00\x00\x0f\xf8\x00\x00\x00\x00\x00\x00\x07\xe0\x00\x00\x00\x00\x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Small_paper=b'P4\n32\n32\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x1f\x1e\x00\x00;\xbf\x00\x001\xf3\x00\x00q\xe1\x80\x00a\xc3\xa0\x00a\x83\xf0\x1fa\x87\xf8?\xe1\x87\x181\xe0\x0e\x180\xe0\x1c80`\x08p\x18 \x00\xe0\x1c\x00\x01\xf0\x0e\x00\x03\xf8\x06\x00\x01\x1c\x06\x00\x00\x0c\x06\x00\x00\x1c\x06\x00\x00\xf8\x0e\x00\x1f\xf0\x06\x00\x1f\x80\x06\x000\x00\x07\x00p\x00\x03\x80\xe0\x00\x01\xc3\xc0\x00\x00\xff\x00\x00\x00>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Small_rock=b'P4\n32\n32\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00?\xf8\x00\x00\x7f\x9c\x00\x00\xe3\x0f\xe0\x03\xc6\x1f\xf0\x07\xc6p8\x0e\xc6`\x18\x0c\xc2@\x1c\x18\xc3@\x0c\x18c\xe3\x0c<q\xff\x0c|8\xf8\x0cf\x1d\xe0\x0cg\x0f\x80\x0cc\x8e\x00\x0cq\xdc\x00\x1c0\xf0\x00\x188`\x00\x18\x1c\xc0\x008\x0f\xc0\x00\xf0\x07\xc0\x03\xe0\x00\xc0\x07\x80\x00\xe0\x1e\x00\x00px\x00\x00?\xe0\x00\x00\x1f\x80\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Small_scissors=b'P4\n32\n32\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\x00\x00\x01\xff\x00\x00\x01\x87\x80\x00\x03\x81\xc0\x00\x03\x00\xe0\x00\x03\x00~\x00\x01\x80?\x80\x01\xc0\x0b\xe0\x00\xf0\x18p\x0f\xf8\x18p\x1f\xff\x10x8\x1f0xp\x000l`\x000\xccp\x01\xf0\xcc0\x03\xb1\x8c?\xfe\x1f\x0c\x1f\xfc\x1e\x0c\x01\xce\xff\x8c\x00\x07\xe1\xdc\x00\x03\x00\xd8\x00\x03\x00\xf8\x00\x03\x01\xf0\x00\x03\xff\xe0\x00\x01\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Smile=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x03\xff\xff\x7f\xff\xc0\x00\x00\x07\xff\x80\x03\xff\xe0\x00\x00\x0f\xfc\x00\x00?\xf0\x00\x00\x1f\xf0\x00\x00\x1f\xf8\x00\x00?\xe0\x00\x00\x07\xfc\x00\x00\x7f\x80\x00\x00\x01\xfe\x00\x00\xff\x00\x00\x00\x00\xff\x00\x00\xfe\x00\x00\x00\x00\x7f\x00\x03\xfc\x00\x00\x00\x00?\x80\x03\xf8\x00\x00\x00\x00\x1f\xc0\x03\xf8\x00\x00\x00\x00\x0f\xc0\x07\xe0\x00\x00\x00\x00\x0f\xe0\x07\xe0\x00\x00\x00\x00\x07\xe0\x0f\xe0\x00\x00\x00\x00\x07\xf0\x0f\xc0\x00\x00\x00\x00\x03\xf0\x1f\xc0?\x00\x01\xfc\x03\xf8\x1f\x80\x7f\xc0\x03\xfe\x01\xf8\x1f\x80\xff\xe0\x07\xff\x01\xf8\x1f\x01\xff\xf0\x0f\xff\x81\xf8?\x03\xfb\xf0\x1f\xef\xc0\xfc?\x03\xe0\xf8\x1f\x07\xc0\xfc?\x03\xc0\xf8\x1f\x07\xc0\xfc?\x07\xc0\xf8\x1e\x03\xc0\xfc?\x03\xc0x\x1e\x03\xe0|?\x03\xc0x\x1e\x03\xc0\xfc?\x01\x80 \x0c\x00\x80\xfc>\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00|?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xf8\x1f\x80\x00\x00\x00\x00\x01\xfc\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x0f\xc0\x00\x00\x00\x00\x01\xf0\x0f\xc0\x0e\x00\x000\x03\xf8\x0f\xe0\x0f\x00\x00x\x07\xe0\x07\xe0\x1f\x00\x00\xf0\x07\xf0\x07\xf0\x0f\x00\x00\xf0\x0f\xe0\x03\xf0\x07\x80\x01\xf0\x0f\xc0\x03\xf8\x07\xc0\x03\xe0\x1f\xc0\x01\xfc\x07\xe0\x07\xe0?\x80\x01\xfe\x03\xfc\x1f\xc0\x7f\x80\x00\xff\x01\xff\xff\x80\xff\x00\x00\x7f\xc0\xff\xfe\x03\xfe\x00\x00?\xe0?\xfc\x07\xfc\x00\x00\x1f\xf0\x0f\xf0\x1f\xf8\x00\x00\x0f\xfe\x00\x00?\xf0\x00\x00\x07\xff\xc0\x03\xff\xe0\x00\x00\x03\xff\xff\x7f\xff\x80\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x03\xff\xff\x80\x00\x00\x00\x00\x00?\xfa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Surprise=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x7f\xff\xff\xfc\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x03\xff\xfd\x7f\xff\xc0\x00\x00\x07\xff\x80\x01\xff\xe0\x00\x00\x0f\xfc\x00\x00\x7f\xf0\x00\x00\x1f\xf8\x00\x00\x1f\xf8\x00\x00?\xc0\x00\x00\x07\xfc\x00\x00\x7f\xc0\x00\x00\x01\xfe\x00\x00\xff\x00\x00\x00\x00\xff\x00\x01\xfe\x00\x00\x00\x00\x7f\x00\x01\xfc\x00\x00\x00\x00?\x80\x03\xf8\x00\x00\x00\x00\x1f\xc0\x03\xf0\x00\x00\x00\x00\x1f\xc0\x07\xf0\x00\x00\x00\x00\x0f\xe0\x07\xe0\x00\x00\x00\x00\x07\xf0\x0f\xc0\x00\x00\x00\x00\x07\xf0\x0f\xc0\x10\x00\x00\x10\x03\xf0\x1f\xc0>\x00\x00|\x01\xf8\x1f\x80\x7f\x00\x00~\x01\xf8\x1f\x80\xff\x00\x00\xff\x01\xf8\x1f\x80\xff\x80\x01\xff\x00\xf8?\x00\xff\x00\x01\xff\x00\xfc?\x00\xff\x80\x01\xff\x00\xfc?\x00\xff\x00\x00\xff\x00\xfc?\x00\xff\x80\x01\xff\x00\xfc>\x00\x7f\x00\x00\xff\x00\xfc?\x00~\x00\x00~\x00|?\x00>\x00\x008\x00\xfc>\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00|?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x03\xc0\x00\x01\xf8\x1f\x80\x00\x07\xe0\x00\x01\xf8\x1f\xc0\x00\x0f\xf0\x00\x01\xf8\x0f\xc0\x00\x0f\xf0\x00\x03\xf0\x0f\xe0\x00\x0f\xf0\x00\x07\xf0\x07\xe0\x00\x0f\xf8\x00\x07\xe0\x07\xf0\x00\x1f\xf0\x00\x0f\xe0\x03\xf8\x00\x0f\xf8\x00\x0f\xc0\x03\xf8\x00\x0f\xf0\x00\x1f\xc0\x01\xfc\x00\x0f\xf0\x00?\x80\x00\xfe\x00\x0f\xe0\x00\x7f\x80\x00\xff\x00\x07\xe0\x00\xff\x00\x00\x7f\xc0\x03\xc0\x03\xfe\x00\x00?\xe0\x00\x00\x07\xfc\x00\x00\x1f\xf8\x00\x00\x1f\xf8\x00\x00\x0f\xfe\x00\x00\x7f\xf0\x00\x00\x07\xff\x80\x03\xff\xe0\x00\x00\x01\xff\xff\xff\xff\x80\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x03\xff\xff\x80\x00\x00\x00\x00\x00/\xfa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Wonderful=b'P4\n64\n64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x02\x00\xff\xff\xff\xff\x00\x00\x07\x03\xff\xff\x7f\xff\xc0\x00\x07\x87\xff\x80\x03\xff\xe0\x00\x1f\xcf\xfc\x00\x00\x7f\xf0\x00\x1f\xdf\xf8\x00\x00\x1f\xf8\x00\x07?\xe0\x00\x00\x07\xfc\x00\x02\x7f\x80\x00\x00\x19\xfe\x00\x02\xff\x00\x00\x00\x1c\xff\x00\x00\xfe\x00\x00\x00>\x7f\x00\x01\xfc\x00\x00\x00\x7f?\x80\x03\xf8\x00\x00\x00\x1c\x1f\xc0\x03\xf0\x00\x00\x00\x18\x1f\xe0\x07\xf0\x00\x00\x00\x08\x0f\xe0\x07\xe0\x00\x00\x00\x00\x07\xe0\x0f\xe0\x00\x00\x00\x00\x07\xf0\x0f\xc0<\x00\x008\x03\xf0\x1f\x80\xff\x00\x00\xff\x01\xf8\x1f\x80\xff\x80\x01\xff\x01\xf8\x1f\x81\xff\x80\x01\xff\x81\xf8?\x83\xff\xc0\x01\xff\xc0\xfc\x1f\x01\xff\xc0\x03\xff\x80\xf8?\x03\xff\xc0\x03\xff\xc0\xfc?\x01\xff\xc0\x03\xff\x80\xfc?\x01\xff\x80\x01\xff\x80\xfc>\x00\xff\x80\x01\xff\x80|?\x00~\x00\x00\xfe\x00\xfc?\x00\x1c\x00\x008\x00\xfc>\x00\x00\x00\x00\x00\x00|?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\xf8\x1f\x80\x00\x00\x00\x00\x01\xfc\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\x80\x00\x00\x00\x00\x01\xf8\x1f\xc0\x00\x00\x00\x01\x03\xf0\x0f\xc0\x00\x00\x00\x01\x83\xf8\x0f\xe0\x00\xff\xff\x03\xc3\xf0\x07\xe0\x00\xff\xff\x0f\xe7\xe0\x07\xf0\x00\xff\xff\x07\xcf\xe0\x03\xf0\x00\x7f\xff\x01\x9f\xc0\x03\xf8\x00\x7f\xfe\x01\x9f\xc0\x01\xfc\x00?\xfc\x00?\x80\x00\xfe\x00\x1f\xf8\x00\x7f\x80\x00\xff\x00\x07\xe0\x00\xff\x00\x00\x7f\x80\x00\x00\x01\xfe\x00\x00?\xe0\x00\x00\x07\xfc\x00\x00\x1f\xf8\x00\x00\x1f\xf8\x00\x00\x0f\xfe\x00\x00\x7f\xf0\x00\x00\x07\xff\xc0\x01\xff\xe0\x00\x00\x03\xff\xff\xff\xff\x80\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00?\xff\xff\xfc\x00\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x03\xff\xff\x80\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
31
mixly/boards/default/micropython/build/lib/eye_picture.py
Normal file
31
mixly/boards/default/micropython/build/lib/eye_picture.py
Normal file
@@ -0,0 +1,31 @@
|
||||
#Take the picture bytes in eye_picture.py
|
||||
#--dahanzimin From the Mixly Team
|
||||
|
||||
Eyes_Angry=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1e\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1f\x80\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1f\xe0\x00\x00\x07\x000\x00\x00\x00\x1c\x7f\x1d\xf8\x00\x00\x07\x000\x00\x00\x00|\x7f\x1c\xfe\x00\x00\x07\x000\x00\x00\x01\xfc\x7f\x1c?\x80\x00\x07\x000\x00\x00\x07\xfc\x7f\x1c\x0f\xe0\x00\x07\x000\x00\x00\x1f\x8c\x7f\x1c\x03\xf8\x00\x07\x000\x00\x00~\x0c\x7f\x1c\x00\xfe\x00\x07\x000\x00\x01\xf8\x0c\x7f\x1c\x00?\x80\x07\x000\x00\x07\xe0\x0c\x7f\x1c\x00\x0f\xe0\x07\x000\x00\x1f\x80\x0c\x7f\x1c\x00\x07\xf8\x07\x000\x00\x7f\x00\x0c\x7f\x1c\x00\x0f\xfe\x07\x000\x01\xfc\x00\x0c\x7f\x1c\x00\x1f\xff\x87\x000\x07\xf6\x80\x0c\x7f\x1c\x00?\x9f\xe7\x000\x1f\xf2\x00\x0c\x7f\x1c\x00\xbf\xbb\xff\x000\x7f\xef\x00\x0c\x7f\x1c\x00\x7f\xfc\xff\x001\xff\xff@\x0c\x7f\x1c\x00\x7f\xfc?\x00?\xff\xff\x00\x0c\x7f\x1c\x00\x7f\xfc\x0f\x00?\xaf\xff@\x0c\x7f\x1c\x00?\xf8\x07\x00>\x0f\xff\x00\x0c\x7f\x1c\x00\xbf\xfa\x07\x008\x07\xfe\x00\x1c\x7f\x0e\x00\x1f\xf0\x0e\x008\x17\xfe\x80\x1c\x7f\x0e\x00\x0f\xe0\x0e\x00<\x03\xfc\x00<\x7f\x0f\x00\x03\x80\x1e\x00\x1c\x04\xf2\x008\x7f\x07\x80\x04 <\x00\x1e\x01\x08\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Awake=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1f\x00\x00\x00\x07\x000\x00\x00\x00|\x7f\x1f\xf8\x00\x00\x07\x000\x00\x00\x07\xfc\x7f\x1f\xff\xc0\x00\x07\x000\x00\x01\xff\xfc\x7f\x1c\x1f\xff\x00\x07\x000\x00?\xfe\x0c\x7f\x1c\x00\xff\xf0\x07\x000\x07\xff\xc0\x0c\x7f\x1c\x00?\xff\x87\x000\x7f\xfe\x00\x0c\x7f\x1c\x01\x7f\xff\xff\x00?\xff\xff\x00\x0c\x7f\x1c\x00~i\xff\x00?\xe1\xfd\xa0\x0c\x7f\x1c\x02\xfeh\x0f\x00<\x03\xf9\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x02\xff\xe8\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x00\xff\xc0\x07\x000\x05\xff\xa0\x0c\x7f\x1c\x01\x7f\xd0\x07\x000\x00\xff\x00\x0c\x7f\x1c\x00\x1f\x00\x07\x000\x00~\x00\x0c\x7f\x1c\x00@@\x07\x000\x00\x81\x00\x0c\x7f\x1c\x00\n\x00\x07\x000\x00(\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Black_eye=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00?\xff\xfc\x00\x7f\x00\x00\x00\x00\x00\x00\x01\xff\xff\xff\x80\x7f\x00\x00\x00\x00\x00\x00\x03\xff\xff\xff\xc0\x7f\x00\x1f\xff\xfe\x00\x00\x07\xc0\x00\x03\xe0\x7f\x00\x7f\xff\xff\xc0\x00\x0f\x00\x00\x00\xf0\x7f\x01\xff\xff\xff\xf0\x00\x1e\x00\x00\x00x\x7f\x03\xfa\xaa\xab\xf8\x00\x1c\x00\x00\x008\x7f\x07\xd2U%|\x008\x00\x00\x00\x1c\x7f\x07\xad\xaa\xda\xbc\x008\x00\x00\x00\x1c\x7f\x0fRU%^\x008\x00\x00\x00\x1c\x7f\x0fm\xaa\xda\xae\x000\x00\x00\x00\x0c\x7f\x1e\x92U$\xaf\x000\x00\x00\x00\x0c\x7f\x1dm\xaa\xdbW\x000\x00\x00\x00\x0c\x7f\x1e\x92U$\xaf\x000\x00\x00\x00\x0c\x7f\x1dm\xaa\xdbW\x000\x00\x00\x00\x0c\x7f\x1c\x92U$\xaf\x000\x00\x00\x00\x0c\x7f\x1fm\xaa\xdbW\x000\x00\x00\x00\x0c\x7f\x1c\x92U$\x97\x000\x00\x00\x00\x0c\x7f\x1f\xff\xff\xff\xff\x000\x00B\x00\x0c\x7f\x1f\xff\xff\xff\xff\x000\x018\x80\x0c\x7f\x1f\xff\xff\xff\xff\x000\x00\x7f\x00\x0c\x7f\x1c\x00\x7f\xc0\x07\x000\x05\xfd\xa0\x0c\x7f\x1c\x00\xfe`\x07\x000\x01\xfc\x80\x0c\x7f\x1c\x02\xfe\xe8\x07\x000\x03\xfb\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x02\xff\xe8\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x00\xff\xe0\x07\x000\x01\xff\x80\x0c\x7f\x1f\xff\xff\xff\xff\x000\x05\xff\xa0\x0c\x7f\x1f\xff\xff\xff\xff\x000\x00\xff\x00\x0c\x7f\x1f\xff\xff\xff\xff\x000\x01<\x80\x0c\x7f\x1dUUUW\x000\x00B\x00\x0c\x7f\x1dT\x92UW\x000\x00\x00\x00\x0c\x7f\x1e\xabm\xaa\xaf\x000\x00\x00\x00\x0c\x7f\x1dT\x92UW\x000\x00\x00\x00\x0c\x7f\x1fKm\xaa\xaf\x000\x00\x00\x00\x0c\x7f\x0e\xb4\x92U\xae\x000\x00\x00\x00\x0c\x7f\x0fKm\xaa^\x008\x00\x00\x00\x1c\x7f\x07\xb4\x92U\xbc\x008\x00\x00\x00\x1c\x7f\x07\xcbm\xaa|\x00<\x00\x00\x00<\x7f\x03\xf4\x92K\xf8\x00\x1c\x00\x00\x008\x7f\x01\xff\xff\xff\xf0\x00\x1e\x00\x00\x00x\x7f\x00\x7f\xff\xff\xc0\x00\x0f\x80\x00\x01\xf0\x7f\x00\x1f\xff\xff\x00\x00\x07\xe0\x00\x07\xe0\x7f\x00\x00\x00\x00\x00\x00\x03\xff\xff\xff\xc0\x7f\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Bottom_left=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x02\x80\x00\x07\x000\x05\x00\x00\x0c\x7f\x1c\x10\x10\x00\x07\x000 @\x00\x0c\x7f\x1c\x07\xc8\x00\x07\x000\x1f\x80\x00\x0c\x7f\x1c_\xf0\x00\x07\x000?\xc0\x00\x0c\x7f\x1c\x1f\x98\x00\x07\x001\x7fh\x00\x0c\x7f\x1c\xbf\x9a\x00\x07\x000\xfep\x00\x0c\x7f\x1c\x7f\xfc\x00\x07\x000\xff\xf0\x00\x0c\x7f\x1c\x7f\xfc\x00\x07\x002\xff\xf4\x00\x0c\x7f\x1c\x7f\xfc\x00\x07\x000\xff\xf0\x00\x0c\x7f\x1c\x7f\xfc\x00\x07\x002\xff\xf4\x00\x0c\x7f\x1c\xbf\xfa\x00\x07\x000\xff\xf0\x00\x0c\x7f\x1c?\xf0\x00\x07\x001\x7f\xe8\x00\x0c\x7f\x1c_\xf4\x00\x07\x000?\xc0\x00\x0c\x7f\x1c\x07\xc0\x00\x07\x000\x1f\x80\x00\x0c\x7f\x1c\x10\x10\x00\x07\x008 @\x00\x1c\x7f\x0e\x02\x80\x00\x0e\x008\n\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Bottom_right=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00(\x07\x000\x00\x00P\x0c\x7f\x1c\x00\x01\x01\x07\x000\x00\x02\x04\x0c\x7f\x1c\x00\x00|\x87\x000\x00\x01\xf8\x0c\x7f\x1c\x00\x05\xff\x07\x000\x00\x03\xfc\x0c\x7f\x1c\x00\x01\xf9\x87\x000\x00\x17\xf6\x8c\x7f\x1c\x00\x0b\xf9\xa7\x000\x00\x0f\xe7\x0c\x7f\x1c\x00\x07\xff\xc7\x000\x00\x0f\xff\x0c\x7f\x1c\x00\x07\xff\xc7\x000\x00/\xffL\x7f\x1c\x00\x07\xff\xc7\x000\x00\x0f\xff\x0c\x7f\x1c\x00\x07\xff\xc7\x000\x00/\xffL\x7f\x1c\x00\x0b\xff\xa7\x000\x00\x0f\xff\x0c\x7f\x1c\x00\x03\xff\x07\x000\x00\x17\xfe\x8c\x7f\x1c\x00\x05\xffG\x000\x00\x03\xfc\x0c\x7f\x1c\x00\x00|\x07\x000\x00\x01\xf8\x0c\x7f\x1c\x00\x01\x01\x07\x008\x00\x02\x04\x1c\x7f\x0e\x00\x00(\x0e\x008\x00\x00\xa0\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Crazy_1=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x01\x08\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\xe0\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x03\xf8\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x07\xfc\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x0f\xe6\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c/\xee\x80\x07\x000\x00\x00\x00\x0c\x7f\x1c\x1f\xff\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x1f\xff\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x1f\xff\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x0f\xfe\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c/\xfe\x80\x07\x000\x00\x00\x00\x0c\x7f\x1c\x07\xfc\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x03\xf8\x00\x07\x000\x00\x01@\x0c\x7f\x1c\x00\xe0\x00\x07\x000\x00\x08\x10\x0c\x7f\x1c\x01\x08\x00\x07\x000\x00\x07\xe0\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x0f\xf0\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00_\xda\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00?\x9c\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00?\xfc\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\xbf\xfd\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00?\xfc\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\xbf\xfd\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00?\xfc\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00_\xfa\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x0f\xf0\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x07\xe0\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x08\x10\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x02\x80\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Crazy_2=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x04 \x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x13\x88\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x07\xf0\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00_\xda\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x1f\xc8\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00?\xbc\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\xbf\xfd\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00?\xfc\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\xbf\xfd\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00?\xfc\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x1f\xf8\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00_\xfa\x0c\x7f\x1c\x00\xa0\x00\x07\x000\x00\x0f\xf0\x0c\x7f\x1c\x04\x04\x00\x07\x000\x00\x13\xc8\x0c\x7f\x1c\x01\xf2\x00\x07\x000\x00\x04 \x0c\x7f\x1c\x17\xfc\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x07\xe6\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c/\xe6\x80\x07\x000\x00\x00\x00\x0c\x7f\x1c\x1f\xff\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x1f\xff\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x1f\xff\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x1f\xff\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c/\xfe\x80\x07\x000\x00\x00\x00\x0c\x7f\x1c\x0f\xfc\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x17\xfd\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x01\xf0\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x04\x04\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\xa0\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Disappointed=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x1f\xf8\x00\x07\xfc\x00\x03\xe0\x7f\x07\x80\x00><\x00\x0f\x1e\x00\x00\xf0\x7f\x07\x00\x00|\x1c\x00\x1e\x0f\x00\x00x\x7f\x0e\x00\x00\xf8\x0e\x00\x1c\x07\x80\x008\x7f\x0e\x00\x01\xf0\x0e\x008\x03\xc0\x00\x1c\x7f\x1c\x00\x03\xe0\x07\x008\x01\xe0\x00\x1c\x7f\x1c\x00\x07\xc0\x07\x008\x00\xf0\x00\x1c\x7f\x1c\x00\x0f\x80\x07\x000\x00x\x00\x0c\x7f\x1c\x00\x1f\x00\x07\x000\x00<\x00\x0c\x7f\x1c\x00>\x00\x07\x000\x00\x1e\x00\x0c\x7f\x1c\x00|@\x07\x000\x00\x9f\x00\x0c\x7f\x1c\x00\xff \x07\x000\x00\x7f\x80\x0c\x7f\x1c\x01\xff\xc0\x07\x000\x00\xff\xc0\x0c\x7f\x1c\x03\xfe`\x07\x000\x05\xfd\xe0\x0c\x7f\x1c\x07\xfeh\x07\x000\x03\xf9\xf0\x0c\x7f\x1c\x0f\xff\xf0\x07\x000\x03\xff\xf8\x0c\x7f\x1c\x1f\xff\xf0\x07\x000\x0b\xff\xfc\x0c\x7f\x1c?\xff\xf0\x07\x000\x03\xff\xde\x0c\x7f\x1c}\xff\xf0\x07\x000\x0b\xff\xdf\x0c\x7f\x1c\xfa\xff\xe8\x07\x000\x03\xff\xc7\x8c\x7f\x1d\xf0\xff\xc0\x07\x000\x05\xff\xa3\xcc\x7f\x1f\xe1\x7f\xd0\x07\x000\x00\xff\x01\xfc\x7f\x1f\xc0\x1f\x00\x07\x000\x00~\x00\xfc\x7f\x1f\x80@@\x07\x000\x00\x81\x00|\x7f\x1f\x00\n\x00\x07\x000\x00(\x00<\x7f\x1e\x00\x00\x00\x07\x000\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Dizzy=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x000\x00\x07\x000\x00\xc0\x00\x0c\x7f\x1c\x00\xf0\x00\x07\x000\x03\xc0\x00\x0c\x7f\x1c\x01\xc0\x00\x07\x000\x07\x00\x00\x0c\x7f\x1c\x03\x9f\xe0\x07\x000\x0e\x7f\x80\x0c\x7f\x1c\x07<\xf8\x07\x000\x1c\xf3\xe0\x0c\x7f\x1c\x06`\x1c\x07\x000\x19\x80p\x0c\x7f\x1c\x0c\xc7\xcc\x07\x0003\x1f0\x0c\x7f\x1c\x0c\xcf\xe6\x07\x0003?\x98\x0c\x7f\x1c\r\x98v\x07\x0006a\xd8\x0c\x7f\x1c\r\x9b3\x07\x0006l\xcc\x0c\x7f\x1c\r\x9b\xb3\x07\x0006n\xcc\x0c\x7f\x1c\r\x9f\xb3\x07\x0006~\xcc\x0c\x7f\x1c\x0c\xcf6\x07\x0003<\xd8\x0c\x7f\x1c\x0e\xe0f\x07\x000;\x81\x98\x0c\x7f\x1c\x06y\xee\x07\x000\x19\xe7\xb8\x0c\x7f\x1c\x03\x1f\x8c\x07\x000\x0c~0\x0c\x7f\x1c\x03\x80\x18\x07\x000\x0e\x00`\x0c\x7f\x1c\x00\xf0p\x07\x000\x03\xc1\xc0\x0c\x7f\x1c\x00\x7f\xe0\x07\x000\x01\xff\x80\x0c\x7f\x1c\x00\x0f\x00\x07\x000\x00<\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Down=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\n\x00\x07\x000\x00(\x00\x0c\x7f\x1c\x00@@\x07\x000\x00\x81\x00\x0c\x7f\x1c\x00\x9f\x00\x07\x000\x00~\x00\x0c\x7f\x1c\x00\x7f\xd0\x07\x000\x00\xff\x00\x0c\x7f\x1c\x00\xfe`\x07\x000\x05\xfd\xa0\x0c\x7f\x1c\x02\xfeh\x07\x000\x03\xf9\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x02\xff\xe8\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x00\x7f\xe0\x07\x008\x05\xff\xa0\x1c\x7f\x0e\x01\x7f\xd0\x0e\x008\x00\xff\x00\x1c\x7f\x0e\x00\x1f\x00\x0e\x00<\x00~\x00<\x7f\x0f\x00@@\x1e\x00\x1c\x00\x81\x008\x7f\x07\x80\x15\x00<\x00\x1e\x00\x14\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Evil=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x0f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\xf0\x00\x00<\x00\x0f\x00\x00\x03\xf0\x7f\x07\xf8\x00\x00\x1c\x00\x1e\x00\x00\x07\xf8\x7f\x0e<\x00\x00\x0e\x00\x1c\x00\x00\x0e8\x7f\x0e\x1e\x00\x00\x0e\x008\x00\x00<\x1c\x7f\x1c\x0f\x00\x00\x07\x008\x00\x00x\x1c\x7f\x1c\x07\x80\x00\x07\x008\x00\x00\xf0\x1c\x7f\x1c\x01\xe0\x00\x07\x000\x00\x01\xe0\x0c\x7f\x1c\x00\xf0\x00\x07\x000\x00\x03\xc0\x0c\x7f\x1c\x00x\x00\x07\x000\x00\x07\x80\x0c\x7f\x1c\x00<\x00\x07\x000\x00\x0e\x00\x0c\x7f\x1c\x00\x1e\x00\x07\x000\x00>\x00\x0c\x7f\x1c\x00O\x00\x07\x000\x00|\x80\x0c\x7f\x1c\x00?\x80\x07\x000\x00\xff\x00\x0c\x7f\x1c\x00\x7f\xe0\x07\x000\x01\xfd\xa0\x0c\x7f\x1c\x00\xfe\xf0\x07\x000\x03\xfc\x80\x0c\x7f\x1c\x02\xfe\xf8\x07\x000\x07\xfb\xc0\x0c\x7f\x1c\x01\xff\xfc\x07\x000\x1f\xff\xd0\x0c\x7f\x1c\x01\xff\xfe\x07\x000?\xff\xc0\x0c\x7f\x1c\x01\xff\xff\x07\x000\x7f\xff\xd0\x0c\x7f\x1c\x00\xff\xe3\xc7\x000\xf3\xff\xc0\x0c\x7f\x1c\x02\xff\xe9\xe7\x001\xe1\xff\x80\x0c\x7f\x1c\x00\x7f\xc0\xf7\x003\xc5\xff\xa0\x0c\x7f\x1c\x00?\x80\x7f\x00?\x00\xff\x00\x0c\x7f\x1c\x00\x0e\x00?\x00>\x01<\x80\x0c\x7f\x1c\x00\x10\x80\x1f\x00<\x00B\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Hurt=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x0f\x008\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00?\x00>\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\xff\x00?\x80\x00\x00\x0c\x7f\x1c\x00\x00\x03\xff\x00?\xe0\x00\x00\x0c\x7f\x1c\x00\x00\x0f\xe7\x001\xf8\x00\x00\x0c\x7f\x1c\x00\x00?\x87\x000~\x00\x00\x0c\x7f\x1c\x00\x00\xfe\x07\x000\x1f\x80\x00\x0c\x7f\x1c\x00\x03\xf8\x07\x000\x07\xe0\x00\x0c\x7f\x1c\x00\x0f\xf0\x07\x000\x03\xf8\x00\x0c\x7f\x1c\x00?\x80\x07\x000\x04\xfe\x00\x0c\x7f\x1c\x00\xff\xe0\x07\x000\x03\xff\x80\x0c\x7f\x1c\x03\xff\xf0\x07\x000\x17\xff\xe0\x0c\x7f\x1c\x0f\xff\x98\x07\x000\x07\xf3\xf8\x0c\x7f\x1c?\xbf\xba\x07\x000\x0f\xef~\x0c\x7f\x1c\xff\x7f\xfc\x07\x000/\xff_\x8c\x7f\x1d\xf8\x7f\xfc\x07\x000\x0f\xff\x07\xec\x7f\x1f\xe0\x7f\xfc\x07\x000/\xffA\xfc\x7f\x1f\x80?\xf8\x07\x000\x0f\xff\x00|\x7f\x1e\x00\xbf\xfa\x07\x008\x07\xfe\x00\x1c\x7f\x0e\x00\x1f\xf0\x0e\x008\x17\xfe\x80\x1c\x7f\x0e\x00\x0f\xe0\x0e\x00<\x03\xfc\x00<\x7f\x0f\x00\x03\x80\x1e\x00\x1c\x04\xf2\x008\x7f\x07\x80\x04 <\x00\x1e\x01\x08\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Knocked_out=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x0f\xff\xfe\x07\x000\x1f\xff\xf8\x0c\x7f\x1c\x0f\xff\xfe\x07\x000?\xff\xfc\x0c\x7f\x1c\x0f\xff\xfe\x07\x000?\xff\xf8\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Love=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x07\xe0\xfc\x07\x000\x0f\x81\xf0\x0c\x7f\x1c\x0f\xd1\xfa\x07\x000\x1fC\xf8\x0c\x7f\x1c\x1f\xeb\xfd\x07\x000?\xa7\xf4\x0c\x7f\x1c\x1f\xff\xfd\x07\x000\x7f\xff\xfa\x0c\x7f\x1c?\xff\xfe\x07\x000\x7f\xff\xfa\x0c\x7f\x1c?\xff\xff\x87\x000\x7f\xff\xfe\x0c\x7f\x1c?\xff\xff\x87\x000\x7f\xff\xfe\x0c\x7f\x1c?\xff\xff\x87\x000\x7f\xff\xfe\x0c\x7f\x1c\x1f\xff\xff\x07\x000\x7f\xff\xfe\x0c\x7f\x1c\x1f\xff\xff\x07\x000\x7f\xff\xfe\x0c\x7f\x1c\x1f\xff\xff\x07\x000?\xff\xfc\x0c\x7f\x1c\x0f\xff\xfe\x07\x000\x1f\xff\xf8\x0c\x7f\x1c\x03\xff\xf8\x07\x000\x0f\xff\xf0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x07\xff\xe0\x0c\x7f\x1c\x00\xff\xe0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x00\x7f\xc0\x07\x000\x01\xff\x80\x0c\x7f\x1c\x00?\x80\x07\x000\x00~\x00\x0c\x7f\x1c\x00\x1f\x00\x07\x000\x00<\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x18\x00\x0c\x7f\x1c\x00\x04\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Middle_left=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x08@\x00\x07\x000 \x80\x00\x0c\x7f\x1c\x03\x80\x00\x07\x000\x07 \x00\x0c\x7f\x1c\x0f\xe0\x00\x07\x000?\x80\x00\x0c\x7f\x1c\x1f\xf0\x00\x07\x001\x7f\xe8\x00\x0c\x7f\x1c?\x98\x00\x07\x000\x7f \x00\x0c\x7f\x1c\xbf\xba\x00\x07\x002\xfe\xf0\x00\x0c\x7f\x1c\x7f\xfc\x00\x07\x000\xff\xf4\x00\x0c\x7f\x1c\x7f\xfc\x00\x07\x002\xff\xf0\x00\x0c\x7f\x1c\x7f\xfc\x00\x07\x000\xff\xf4\x00\x0c\x7f\x1c?\xf8\x00\x07\x002\xff\xf0\x00\x0c\x7f\x1c\xbf\xfa\x00\x07\x000\x7f\xe0\x00\x0c\x7f\x1c\x1f\xf0\x00\x07\x001\x7f\xe8\x00\x0c\x7f\x1c\x0f\xe0\x00\x07\x000?\xc0\x00\x0c\x7f\x1c\x03\x80\x00\x07\x000O \x00\x0c\x7f\x1c\x08@\x00\x07\x000\x10\x80\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Middle_right=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x84\x07\x000\x00\x02\x08\x0c\x7f\x1c\x00\x008\x07\x000\x00\x00r\x0c\x7f\x1c\x00\x00\xfe\x07\x000\x00\x03\xf8\x0c\x7f\x1c\x00\x01\xff\x07\x000\x00\x17\xfe\x8c\x7f\x1c\x00\x03\xf9\x87\x000\x00\x07\xf2\x0c\x7f\x1c\x00\x0b\xfb\xa7\x000\x00\x0f\xef\x0c\x7f\x1c\x00\x07\xff\xc7\x000\x00/\xffL\x7f\x1c\x00\x07\xff\xc7\x000\x00\x0f\xffL\x7f\x1c\x00\x07\xff\xc7\x000\x00/\xff\x0c\x7f\x1c\x00\x03\xff\x87\x000\x00\x0f\xffL\x7f\x1c\x00\x0b\xff\xa7\x000\x00\x07\xfe\x0c\x7f\x1c\x00\x01\xff\x07\x000\x00\x17\xfe\x8c\x7f\x1c\x00\x00\xfe\x07\x000\x00\x03\xfc\x0c\x7f\x1c\x00\x008\x07\x000\x00\x04\xf2\x0c\x7f\x1c\x00\x00\x84\x07\x000\x00\x01\x08\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Neutral=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00!\x00\x07\x000\x00\x82\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x1c\x80\x0c\x7f\x1c\x00?\x80\x07\x000\x00\xfe\x00\x0c\x7f\x1c\x00\x7f\xc0\x07\x000\x05\xff\xa0\x0c\x7f\x1c\x00\xfe`\x07\x000\x01\xfc\x80\x0c\x7f\x1c\x02\xfe\xe8\x07\x000\x03\xfb\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x00\xff\xe0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x02\xff\xe8\x07\x000\x01\xff\x80\x0c\x7f\x1c\x00\x7f\xc0\x07\x000\x05\xff\xa0\x0c\x7f\x1c\x00?\x80\x07\x000\x00\xff\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x01<\x80\x0c\x7f\x1c\x00!\x00\x07\x000\x00B\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Nuclear=b"P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x1e\x00\x07\x000\x00<\x00\x0c\x7f\x1c\x00\xf3\xc0\x07\x000\x01\xe7\x80\x0c\x7f\x1c\x03\x800\x07\x000\x07\x00`\x0c\x7f\x1c\x06\x00\x08\x07\x000\x0c\x00\x10\x0c\x7f\x1c\r\x80$\x07\x000\x1b\x00H\x0c\x7f\x1c\x1b\x80r\x07\x0007\x00\xe4\x0c\x7f\x1c\x13\xc0\xfb\x07\x000'\x81\xf6\x0c\x7f\x1c7\xe0\xfd\x07\x000o\xc1\xfa\x0c\x7f\x1c/\xe1\xfd\x87\x000_\xc3\xfb\x0c\x7f\x1c/\xe1\xfc\x87\x000_\xc3\xf9\x0c\x7f\x1co\xe4\xfe\x87\x000\xdf\xc9\xfd\x0c\x7f\x1cO\xce\xfe\x87\x000\x9f\x9d\xfd\x0c\x7f\x1c@\x1e\x00\x87\x000\x80<\x01\x0c\x7f\x1c@\x0c\x00\x87\x000\x80\x18\x01\x0c\x7f\x1c \x00\x00\x87\x000@\x00\x01\x0c\x7f\x1c \x0e\x00\x87\x000@\x1c\x01\x0c\x7f\x1c \x1f\x01\x87\x000@>\x03\x0c\x7f\x1c\x10?\x01\x07\x000 ~\x02\x0c\x7f\x1c\x18?\x82\x07\x0000\x7f\x04\x0c\x7f\x1c\x08\x7f\x86\x07\x000\x10\xff\x0c\x0c\x7f\x1c\x04\x7f\xcc\x07\x000\x08\xff\x98\x0c\x7f\x1c\x03\x1e\x18\x07\x000\x06<0\x0c\x7f\x1c\x01\xc0`\x07\x000\x03\x80\xc0\x0c\x7f\x1c\x00\x7f\x80\x07\x000\x00\xff\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f"
|
||||
Pinch_left=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x0c\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1d\x7f\xbd\x00\x07\x00:\xfe\xfc\x00\x1c\x7f\x1c\x7f\xfc\x00\x07\x002\xff\xf0\x00\x0c\x7f\x1c\x7f\xfc\x00\x07\x000\xff\xf4\x00\x0c\x7f\x1c?\xf8\x00\x07\x002\xff\xf0\x00\x0c\x7f\x1c\xbf\xfa\x00\x07\x000\x7f\xe0\x00\x0c\x7f\x1c\x1f\xf0\x00\x07\x000\x7f\xe8\x00\x0c\x7f\x1c\x0f\xe0\x00\x07\x000\xbf\xd0\x00\x0c\x7f\x1c\x03\x80\x00\x07\x000\x0f\x00\x00\x0c\x7f\x1c\x18`\x00\x07\x0000\xc0\x00\x1c\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Pinch_middle=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x0c\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1c\x05\xfe\xf4\x07\x008\x0b\xfb\xf0\x1c\x7f\x1c\x01\xff\xf0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x00\xff\xe0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x02\xff\xe8\x07\x000\x01\xff\x80\x0c\x7f\x1c\x00\x7f\xc0\x07\x000\x01\xff\xa0\x0c\x7f\x1c\x00?\x80\x07\x000\x02\xff@\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00<\x00\x0c\x7f\x1c\x00a\x80\x07\x000\x00\xc3\x00\x1c\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Pinch_right=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x0c\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1c\x00\x17\xfb\xd7\x008\x00/\xef\\\x7f\x1c\x00\x07\xff\xc7\x000\x00\x0f\xffL\x7f\x1c\x00\x07\xff\xc7\x000\x00/\xff\x0c\x7f\x1c\x00\x03\xff\x87\x000\x00\x0f\xffL\x7f\x1c\x00\x0b\xff\xa7\x000\x00\x07\xfe\x0c\x7f\x1c\x00\x01\xff\x07\x000\x00\x07\xfe\x8c\x7f\x1c\x00\x00\xfe\x07\x000\x00\x0b\xfd\x0c\x7f\x1c\x00\x008\x07\x000\x00\x00\xf0\x0c\x7f\x1c\x00\x01C\x07\x000\x00\x03\x0c\x1c\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Tear=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1e\x00\x00\x00\x0f\x008\x00\x00\x00\x1c\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1c\x00\xbf\xa0\x07\x008\x02\xfe@\x1c\x7f\x1c\x00\x7f\xc0\x07\x000\x00\xff\x00\x0c\x7f\x1c\x00\xfe`\x07\x000\x05\xfd\xa0\x0c\x7f\x1c\x02\xfeh\x07\x000\x03\xf9\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x00\xff\xe0\x07\x000\x03\xff\xc0\x0c\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00 \x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00 \x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00 \x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x000\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00p\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00p\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\xf8\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x01\xfc\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x01\xf6\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x03\xfa\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x03\xfe\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x03\xfe\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x01\xfe\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\xfc\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00p\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Tired_left=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x1c\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1c\xbf\xba\x00\x07\x00:\xfet\x00\x1c\x7f\x1c\x7f\xf8\x00\x07\x000\xff\xf0\x00\x0c\x7f\x1c\x7f\xfc\x00\x07\x002\xff\xf4\x00\x0c\x7f\x1c\x7f\xfc\x00\x07\x000\xff\xf0\x00\x0c\x7f\x1c\x7f\xfc\x00\x07\x002\xff\xf4\x00\x0c\x7f\x1c\xbf\xfa\x00\x07\x000\xff\xf0\x00\x0c\x7f\x1c\x1f\xf8\x00\x07\x009\x7f\xe8\x00\x1c\x7f\x0e_\xf4\x00\x0e\x008?\xc0\x00\x1c\x7f\x0e\x07\xc0\x00\x0e\x00<\x1f\x80\x00<\x7f\x0f\x10\x10\x00\x1e\x00\x1c @\x008\x7f\x07\x85@\x00<\x00\x1e\x05\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Tired_middle=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x1c\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1c\x02\xff\xe8\x07\x008\x0b\xfb\xd0\x1c\x7f\x1c\x01\xff\xf0\x07\x000\x03\xff\xd0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x00\xff\xe0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x02\xff\xe8\x07\x000\x01\xff\x80\x0c\x7f\x1c\x00\x7f\xc0\x07\x008\x05\xff\xa0\x1c\x7f\x0e\x00?\x80\x0e\x008\x00\xff\x00\x1c\x7f\x0e\x00\x0e\x00\x0e\x00<\x01<\x80<\x7f\x0f\x00!\x00\x1e\x00\x1c\x00B\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Tired_right=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x1c\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1f\xff\xff\xff\xff\x00?\xff\xff\xff\xfc\x7f\x1c\x00\x0b\xfb\xa7\x008\x00/\xe7\\\x7f\x1c\x00\x07\xff\x87\x000\x00\x0f\xff\x0c\x7f\x1c\x00\x07\xff\xc7\x000\x00/\xffL\x7f\x1c\x00\x07\xff\xc7\x000\x00\x0f\xff\x0c\x7f\x1c\x00\x07\xff\xc7\x000\x00/\xffL\x7f\x1c\x00\x0b\xff\xa7\x000\x00\x0f\xff\x0c\x7f\x1c\x00\x01\xff\x87\x008\x00\x17\xfe\x9c\x7f\x0e\x00\x05\xffN\x008\x00\x03\xfc\x1c\x7f\x0e\x00\x00|\x0e\x00<\x00\x01\xf8<\x7f\x0f\x00\x01\x01\x1e\x00\x1c\x00\x02\x048\x7f\x07\x80\x00(<\x00\x1e\x00\x00Px\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Toxic=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x008\x00\x0c\x7f\x1c\x00\x7f@\x07\x000\x00\xff\x00\x0c\x7f\x1c\x00\x7f\xc0\x07\x000\x01\xff\x00\x0c\x7f\x1c\x00\xff\xe0\x07\x000\x03\xff\x80\x0c\x7f\x1c\x00\xff\xe0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x01\xc4p\x07\x000\x03\x18\xc0\x0c\x7f\x1c\x01\xc4p\x07\x000\x03\x08\xc0\x0c\x7f\x1c\x00\xce`\x07\x000\x03\x99\xc0\x0c\x7f\x1c\x00\xf9\xe0\x07\x000\x01\xe7\x80\x0c\x7f\x1c\x00y\xc0\x07\x000\x00\xe7\x00\x0c\x7f\x1c\x04\x1f\x02\x07\x000\x18>\x0c\x0c\x7f\x1c\x0f\x8a\x1e\x07\x000?\x10<\x0c\x7f\x1c\x0c\xf0\xf3\x07\x0003\xe1\xec\x0c\x7f\x1c\x00>@\x07\x000\x00|\x00\x0c\x7f\x1c\r\xe3\xe6\x07\x000\x1b\xcf\xc8\x0c\x7f\x1c\x0f\xc0\xfe\x07\x000\x1f\x81\xfc\x0c\x7f\x1c\x06\x00\x0e\x07\x000\x0c\x008\x0c\x7f\x1c\x06\x00\x0c\x07\x000\x08\x00\x18\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Up=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00!\x00\x1c\x00\x1e\x00\x82\x00x\x7f\x0e\x00\x0e\x00\x0e\x00\x1c\x00\x1c\x808\x7f\x0e\x00?\x80\x0e\x008\x00\xfe\x00\x1c\x7f\x1c\x00\x7f\xc0\x07\x008\x05\xff\xa0\x1c\x7f\x1c\x00\xfe`\x07\x008\x01\xfc\x80\x1c\x7f\x1c\x02\xfe\xe8\x07\x000\x03\xfb\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x01\xff\xf0\x07\x000\x0b\xff\xd0\x0c\x7f\x1c\x00\xff\xe0\x07\x000\x03\xff\xc0\x0c\x7f\x1c\x02\xff\xe8\x07\x000\x01\xff\x80\x0c\x7f\x1c\x00\x7f\xc0\x07\x000\x05\xff\xa0\x0c\x7f\x1c\x00?\x80\x07\x000\x00\xff\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x01<\x80\x0c\x7f\x1c\x00!\x00\x07\x000\x00B\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Winking=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x1f\xff\xff\x00\x00\x00?\xff\xfc\x00\x7f\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff\x80\x7f\x01\xff\xff\xff\xf0\x00\x03\xff\xff\xff\xc0\x7f\x03\xe0\x00\x00\xf8\x00\x07\xc0\x00\x03\xe0\x7f\x07\x80\x00\x00<\x00\x0f\x00\x00\x00\xf0\x7f\x07\x00\x00\x00\x1c\x00\x1e\x00\x00\x00x\x7f\x0e\x00\x00\x00\x0e\x00\x1c\x00\x00\x008\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00!\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00?\x80\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x7f\xc0\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\xfe`\x07\x000\x00\x00\x00\x0c\x7f\x1c\x02\xfe\xe8\x07\x000\x00\x00\x00\x0c\x7f\x1c\x01\xff\xf0\x07\x00?\xff\xff\xff\xfc\x7f\x1c\x01\xff\xf0\x07\x00?\xff\xff\xff\xfc\x7f\x1c\x01\xff\xf0\x07\x00?\xff\xff\xff\xfc\x7f\x1c\x00\xff\xe0\x07\x000\x00\x00\x00\x0c\x7f\x1c\x02\xff\xe8\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x7f\xc0\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00?\x80\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x0e\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00!\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x000\x00\x00\x00\x0c\x7f\x1c\x00\x00\x00\x07\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x008\x00\x00\x00\x1c\x7f\x0e\x00\x00\x00\x0e\x00<\x00\x00\x00<\x7f\x0f\x00\x00\x00\x1e\x00\x1c\x00\x00\x008\x7f\x07\x80\x00\x00<\x00\x1e\x00\x00\x00x\x7f\x03\xc0\x00\x00x\x00\x0f\x80\x00\x01\xf0\x7f\x01\xf8\x00\x03\xf0\x00\x07\xe0\x00\x07\xe0\x7f\x00\xff\xff\xff\xe0\x00\x03\xff\xff\xff\xc0\x7f\x00?\xff\xff\x80\x00\x00\xff\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
91
mixly/boards/default/micropython/build/lib/gnss.py
Normal file
91
mixly/boards/default/micropython/build/lib/gnss.py
Normal file
@@ -0,0 +1,91 @@
|
||||
"""
|
||||
GNSS
|
||||
|
||||
Micropython library for the GNSS(NMEA0183/GPS,DBS)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
from time import sleep_ms
|
||||
from ubinascii import unhexlify
|
||||
|
||||
class NMEA0183:
|
||||
def __init__(self, uart, baudrate=9600, timeout=200):
|
||||
self._uart=uart
|
||||
self._uart.init(baudrate=baudrate, timeout=timeout, rxbuf=1024)
|
||||
self.time=[None, None, None, None, None, None]
|
||||
self.locate=['', None, '', None, None, None, None] #0'1经度,2'3纬度,4海拔m,5速度m/s,6航向°
|
||||
self.status=[False, ' ', 0] #有效标注,定位模式,卫星量
|
||||
if not self._chip_id():
|
||||
raise AttributeError("Cannot find a GNSS device")
|
||||
|
||||
def _crc8(self, buffer):
|
||||
'''对数据进行CRC校验'''
|
||||
crc = 0x00
|
||||
for byte in buffer:
|
||||
crc ^= byte
|
||||
return crc & 0xff
|
||||
|
||||
def _chip_id(self):
|
||||
for _ in range(10):
|
||||
sleep_ms(300)
|
||||
if self.any():
|
||||
self._uart.write(("$PCAS02,1000*2E\r\n").encode()) #更新频率1HZ
|
||||
self._uart.write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n".encode()) #只加载GNGGA和GNRMC
|
||||
return True
|
||||
|
||||
def _judge(self, buffer, dlen):
|
||||
try:
|
||||
data=buffer.strip().decode().split(',')
|
||||
if len(data) == dlen:
|
||||
if unhexlify(data[-1][-2:])[0] == self._crc8(buffer[1:-5]):
|
||||
return True,data
|
||||
return False,None
|
||||
except :
|
||||
return False,None
|
||||
|
||||
def any(self):
|
||||
flag_rmc,flag_gga=False,False
|
||||
while self._uart.any():
|
||||
_data=self._uart.readline()
|
||||
if b'$GNGGA' in _data:
|
||||
flag_gga,data=self._judge(_data, 15)
|
||||
#print("GGA----",flag_gga)
|
||||
if flag_gga:
|
||||
self.time[3]= int(data[1][0:2]) if data[1] else None
|
||||
self.time[4]= int(data[1][2:4]) if data[1] else None
|
||||
self.time[5]= int(data[1][4:6]) if data[1] else None
|
||||
self.locate[0]= data[5]
|
||||
self.locate[1]= int(data[4][:3])+int(data[4][3:].replace('.',''))/6000000 if data[4] else None
|
||||
self.locate[2]= data[3]
|
||||
self.locate[3]= int(data[2][:2])+int(data[2][2:].replace('.',''))/6000000 if data[2] else None
|
||||
self.locate[4]= float(data[9]) if data[3] else None
|
||||
self.status[0]= False if '0' in data[6] else True
|
||||
self.status[2]= int(data[7])
|
||||
if b'$GNRMC' in _data:
|
||||
flag_rmc,data=self._judge(_data, 14)
|
||||
#print("RMC----",flag_rmc)
|
||||
if flag_rmc:
|
||||
self.time[0]= int(data[9][4:6])+2000 if data[9] else None
|
||||
self.time[1]= int(data[9][2:4]) if data[9] else None
|
||||
self.time[2]= int(data[9][0:2]) if data[9] else None
|
||||
self.time[3]= int(data[1][0:2])+8 if data[1] else None
|
||||
self.time[4]= int(data[1][2:4]) if data[1] else None
|
||||
self.time[5]= int(data[1][4:6]) if data[1] else None
|
||||
self.locate[0]= data[6]
|
||||
self.locate[1]= int(data[5][:3])+int(data[5][3:].replace('.',''))/6000000 if data[5] else None
|
||||
self.locate[2]= data[4]
|
||||
self.locate[3]= int(data[3][:2])+int(data[3][2:].replace('.',''))/6000000 if data[3] else None
|
||||
self.locate[5]= round(float(data[7])*0.514, 2) if data[7] else None
|
||||
self.locate[6]= float(data[8]) if data[8] else None
|
||||
self.status[0]= False if 'V' in data[2] else True
|
||||
self.status[1]= data[12]
|
||||
return flag_rmc | flag_gga
|
||||
|
||||
def time(self):
|
||||
return tuple(self.time)
|
||||
|
||||
def locate(self):
|
||||
return tuple(self.locate)
|
||||
|
||||
def status(self):
|
||||
return tuple(self.status)
|
||||
87
mixly/boards/default/micropython/build/lib/hmac.py
Normal file
87
mixly/boards/default/micropython/build/lib/hmac.py
Normal file
@@ -0,0 +1,87 @@
|
||||
# Implements the hmac module from the Python standard library.
|
||||
|
||||
|
||||
class HMAC:
|
||||
def __init__(self, key, msg=None, digestmod=None):
|
||||
if not isinstance(key, (bytes, bytearray)):
|
||||
raise TypeError("key: expected bytes/bytearray")
|
||||
|
||||
import hashlib
|
||||
|
||||
if digestmod is None:
|
||||
# TODO: Default hash algorithm is now deprecated.
|
||||
digestmod = hashlib.md5
|
||||
|
||||
if callable(digestmod):
|
||||
# A hashlib constructor returning a new hash object.
|
||||
make_hash = digestmod # A
|
||||
elif isinstance(digestmod, str):
|
||||
# A hash name suitable for hashlib.new().
|
||||
make_hash = lambda d=b"": getattr(hashlib, digestmod)(d)
|
||||
else:
|
||||
# A module supporting PEP 247.
|
||||
make_hash = digestmod.new # C
|
||||
|
||||
self._outer = make_hash()
|
||||
self._inner = make_hash()
|
||||
|
||||
self.digest_size = getattr(self._inner, "digest_size", None)
|
||||
# If the provided hash doesn't support block_size (e.g. built-in
|
||||
# hashlib), 64 is the correct default for all built-in hash
|
||||
# functions (md5, sha1, sha256).
|
||||
self.block_size = getattr(self._inner, "block_size", 64)
|
||||
|
||||
# Truncate to digest_size if greater than block_size.
|
||||
if len(key) > self.block_size:
|
||||
key = make_hash(key).digest()
|
||||
|
||||
# Pad to block size.
|
||||
key = key + bytes(self.block_size - len(key))
|
||||
|
||||
self._outer.update(bytes(x ^ 0x5C for x in key))
|
||||
self._inner.update(bytes(x ^ 0x36 for x in key))
|
||||
|
||||
if msg is not None:
|
||||
self.update(msg)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return "hmac-" + getattr(self._inner, "name", type(self._inner).__name__)
|
||||
|
||||
def update(self, msg):
|
||||
self._inner.update(msg)
|
||||
|
||||
def copy(self):
|
||||
if not hasattr(self._inner, "copy"):
|
||||
# Not supported for built-in hash functions.
|
||||
raise NotImplementedError()
|
||||
# Call __new__ directly to avoid the expensive __init__.
|
||||
other = self.__class__.__new__(self.__class__)
|
||||
other.block_size = self.block_size
|
||||
other.digest_size = self.digest_size
|
||||
other._inner = self._inner.copy()
|
||||
other._outer = self._outer.copy()
|
||||
return other
|
||||
|
||||
def _current(self):
|
||||
h = self._outer
|
||||
if hasattr(h, "copy"):
|
||||
# built-in hash functions don't support this, and as a result,
|
||||
# digest() will finalise the hmac and further calls to
|
||||
# update/digest will fail.
|
||||
h = h.copy()
|
||||
h.update(self._inner.digest())
|
||||
return h
|
||||
|
||||
def digest(self):
|
||||
h = self._current()
|
||||
return h.digest()
|
||||
|
||||
def hexdigest(self):
|
||||
import binascii
|
||||
|
||||
return str(binascii.hexlify(self.digest()), "utf-8")
|
||||
|
||||
|
||||
def new(key, msg=None, digestmod=None):
|
||||
return HMAC(key, msg, digestmod)
|
||||
88
mixly/boards/default/micropython/build/lib/hp203x.py
Normal file
88
mixly/boards/default/micropython/build/lib/hp203x.py
Normal file
@@ -0,0 +1,88 @@
|
||||
"""
|
||||
HP203X
|
||||
|
||||
MicroPython library for the HP203X(Air pressure sensor)
|
||||
=======================================================
|
||||
|
||||
#Changed from circuitpython to micropython 20220211
|
||||
#Format unified 20220623
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
HP203X_ADDRESS = const(0x76)
|
||||
HP203X_REG_RST = const(0x06)
|
||||
HP203X_REG_RDY = const(0x0D)
|
||||
HP20X_READ_P = const(0x30)
|
||||
HP20X_READ_H = const(0x31)
|
||||
HP20X_READ_T = const(0x32)
|
||||
HP20X_READ_CAL = const(0x28)
|
||||
HP20X_WR_CONVERT_CMD = const(0x40)
|
||||
|
||||
#转换时间 越大时间越久
|
||||
#HP20X_CONVERT_OSR4096 =0<<2
|
||||
HP20X_CONVERT_OSR2048 =1<<2
|
||||
#HP20X_CONVERT_OSR1024 =2<<2
|
||||
#HP20X_CONVERT_OSR512 =3<<2
|
||||
#HP20X_CONVERT_OSR256 =4<<2
|
||||
#HP20X_CONVERT_OSR128 =5<<2
|
||||
|
||||
class HP203X:
|
||||
def __init__(self, i2c_bus,cal=False):
|
||||
self._device = i2c_bus
|
||||
self._address = HP203X_ADDRESS
|
||||
self.data_reg = bytearray(3)
|
||||
self._buffer = bytearray(1)
|
||||
self.osr = HP20X_CONVERT_OSR2048 #SET time
|
||||
|
||||
if self._read_rdy()&0x40 ==0:
|
||||
raise AttributeError("Cannot find a HP203X")
|
||||
|
||||
self._rst() #Reset
|
||||
time.sleep(0.1)
|
||||
if cal: #Calibration
|
||||
self._write_cmd(HP20X_WR_CONVERT_CMD|self.osr)
|
||||
time.sleep(0.1)
|
||||
self._calibration()
|
||||
print("calibration")
|
||||
|
||||
def _read_data(self, address):
|
||||
self._buffer[0] = address & 0xFF
|
||||
self._device.writeto(self._address,self._buffer)
|
||||
self._device.readfrom_into(self._address,self.data_reg)
|
||||
return self.data_reg
|
||||
|
||||
def _write_cmd(self,command):
|
||||
self._buffer[0] = command & 0xFF
|
||||
self._device.writeto(self._address,self._buffer)
|
||||
|
||||
def _read_rdy(self):
|
||||
return self._read_data(HP203X_REG_RDY)[0]
|
||||
|
||||
def _calibration(self):
|
||||
self._write_cmd(HP20X_READ_CAL)
|
||||
|
||||
def _rst(self):
|
||||
self._write_cmd(HP203X_REG_RST)
|
||||
|
||||
def u2s(self,n):
|
||||
return n if n < (1 << 23) else n - (1 << 24)
|
||||
|
||||
def get_data(self,flag):
|
||||
self._write_cmd(HP20X_WR_CONVERT_CMD|self.osr)
|
||||
time.sleep(0.1)
|
||||
self._read_data(flag)
|
||||
hp_data=(self.data_reg[0]<<16)|(self.data_reg[1]<<8)|self.data_reg[2]
|
||||
return self.u2s(hp_data)/100
|
||||
|
||||
def pressure(self):
|
||||
return self.get_data(HP20X_READ_P)
|
||||
|
||||
def altitude(self):
|
||||
return self.get_data(HP20X_READ_H)
|
||||
|
||||
def temperature(self):
|
||||
return self.get_data(HP20X_READ_T)
|
||||
59
mixly/boards/default/micropython/build/lib/ht16k33.py
Normal file
59
mixly/boards/default/micropython/build/lib/ht16k33.py
Normal file
@@ -0,0 +1,59 @@
|
||||
"""
|
||||
HT16K33-framebuf
|
||||
|
||||
Micropython library for the HT16K33 Matrix16x8
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20230411
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import uframebuf
|
||||
from micropython import const
|
||||
|
||||
_HT16K33_BLINK_CMD = const(0x80)
|
||||
_HT16K33_BLINK_DISPLAYON = const(0x01)
|
||||
_HT16K33_CMD_BRIGHTNESS = const(0xE0)
|
||||
_HT16K33_OSCILATOR_ON = const(0x21)
|
||||
|
||||
class HT16K33(uframebuf.FrameBuffer_Ascall):
|
||||
def __init__(self, i2c, address=0x70, brightness=0.3, width=16, height=8):
|
||||
self._i2c = i2c
|
||||
self._address = address
|
||||
self._blink_rate=0
|
||||
self._brightness=brightness
|
||||
self._buffer = bytearray((width + 7) // 8 * height)
|
||||
super().__init__(self._buffer, width, height, uframebuf.MONO_HMSB)
|
||||
self._write_cmd(_HT16K33_OSCILATOR_ON)
|
||||
self.blink_rate(0)
|
||||
self.set_brightness(brightness)
|
||||
self.fill(0)
|
||||
self.show()
|
||||
|
||||
def _write_cmd(self, val):
|
||||
'''I2C write command'''
|
||||
self._i2c.writeto(self._address,val.to_bytes(1, 'little'))
|
||||
|
||||
def blink_rate(self, rate=None):
|
||||
if rate is None:
|
||||
return self._blink_rate
|
||||
if not 0 <= rate <= 3:
|
||||
raise ValueError("Blink rate must be an integer in the range: 0-3")
|
||||
rate = rate & 0x03
|
||||
self._blink_rate = rate
|
||||
self._write_cmd(_HT16K33_BLINK_CMD | _HT16K33_BLINK_DISPLAYON | rate << 1)
|
||||
|
||||
def get_brightness(self):
|
||||
return self._brightness
|
||||
|
||||
def set_brightness(self, brightness):
|
||||
if not 0.0 <= brightness <= 1.0:
|
||||
raise ValueError("Brightness must be a decimal number in the range: 0.0-1.0")
|
||||
self._brightness = brightness
|
||||
xbright = round(15 * brightness)
|
||||
xbright = xbright & 0x0F
|
||||
self._write_cmd(_HT16K33_CMD_BRIGHTNESS | xbright)
|
||||
|
||||
def show(self):
|
||||
"""Refresh the display and show the changes."""
|
||||
self._i2c.writeto_mem(self._address, 0x00, self._buffer)
|
||||
305
mixly/boards/default/micropython/build/lib/huskylens.py
Normal file
305
mixly/boards/default/micropython/build/lib/huskylens.py
Normal file
@@ -0,0 +1,305 @@
|
||||
"""
|
||||
HuskyLens
|
||||
|
||||
MicroPython library for the HuskyLens-I2C(DF)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20220224
|
||||
#base on https://github.com/HuskyLens/HUSKYLENSPython 20220623
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import time
|
||||
from ubinascii import unhexlify,hexlify
|
||||
|
||||
commandHeaderAndAddress = "55AA11"
|
||||
algorthimsByteID = {
|
||||
"ALGORITHM_OBJECT_TRACKING": "0100", #物体追踪
|
||||
"ALGORITHM_FACE_RECOGNITION": "0000", #人脸识别
|
||||
"ALGORITHM_OBJECT_RECOGNITION": "0200", #物体识别
|
||||
"ALGORITHM_LINE_TRACKING": "0300", #巡线
|
||||
"ALGORITHM_COLOR_RECOGNITION": "0400", #颜色识别
|
||||
"ALGORITHM_TAG_RECOGNITION": "0500", #标签识别
|
||||
"ALGORITHM_OBJECT_CLASSIFICATION": "0600", #物体分类
|
||||
"ALGORITHM_QR_CODE_RECOGNTITION" : "0700", #二维码识别(教育版独有)
|
||||
"ALGORITHM_BARCODE_RECOGNTITION":"0800", #条形码识别(教育版独有)
|
||||
}
|
||||
|
||||
class Arrow:
|
||||
def __init__(self, xTail, yTail , xHead , yHead, ID):
|
||||
self.xTarget=xTail
|
||||
self.yTarget=yTail
|
||||
self.xOrigin=xHead
|
||||
self.yOrigin=yHead
|
||||
self.id=ID
|
||||
self.learned= True if ID > 0 else False
|
||||
self.type="arrows"
|
||||
|
||||
class Block:
|
||||
def __init__(self, x, y , width , height, ID):
|
||||
self.xCenter = x
|
||||
self.yCenter=y
|
||||
self.width=width
|
||||
self.height=height
|
||||
self.id=ID
|
||||
self.learned= True if ID > 0 else False
|
||||
self.type="blocks"
|
||||
|
||||
class HuskyLens:
|
||||
def __init__(self, i2c,address=0x32):
|
||||
self._address = address
|
||||
self.checkOnceAgain=True
|
||||
self._device = i2c
|
||||
self._buffer=[]
|
||||
self._learned_number=0
|
||||
if not self.knock():
|
||||
raise AttributeError("Cannot find a HuskyLens")
|
||||
|
||||
def _write_cmd(self, cmd):
|
||||
'''Write memory address'''
|
||||
self._device.writeto(self._address, unhexlify(cmd))
|
||||
|
||||
def _read_cmd(self, nbytes):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom(self._address, nbytes)
|
||||
|
||||
def _checksum(self, hexStr):
|
||||
'''data checksums'''
|
||||
total = 0
|
||||
for i in range(0, len(hexStr), 2):
|
||||
total += int(hexStr[i:i+2], 16)
|
||||
hexStr = hex(total)[-2:]
|
||||
return hexStr
|
||||
|
||||
def _read_data(self):
|
||||
'''Read data'''
|
||||
while True:
|
||||
time.sleep(0.01)
|
||||
buffer = self._read_cmd(5)
|
||||
if buffer[0] == 0x55:
|
||||
break
|
||||
buffer += self._read_cmd(int(buffer[3])+1)
|
||||
strs=hexlify(buffer).decode()
|
||||
|
||||
headers = strs[0:4]
|
||||
address = strs[4:6]
|
||||
data_length = int(strs[6:8], 16)
|
||||
command = strs[8:10]
|
||||
if(data_length > 0):
|
||||
data = strs[10:10+data_length*2]
|
||||
else:
|
||||
data = ''
|
||||
checkSum = strs[2*(6+data_length-1):2*(6+data_length-1)+2]
|
||||
return [headers, address, data_length, command, data, checkSum]
|
||||
|
||||
def getBlockOrArrowCommand(self):
|
||||
commandSplit = self._read_data()
|
||||
isBlock = True if commandSplit[3] == "2a" else False
|
||||
return (commandSplit[4],isBlock)
|
||||
|
||||
def processReturnData(self):
|
||||
inProduction = True
|
||||
byteString=""
|
||||
if inProduction :
|
||||
commandSplit = self._read_data()
|
||||
|
||||
if commandSplit[3] == "2e":
|
||||
return "Knock Recieved"
|
||||
else:
|
||||
returnData = []
|
||||
numberOfBlocksOrArrow = int(commandSplit[4][2:4]+commandSplit[4][0:2], 16)
|
||||
self._learned_number = int(commandSplit[4][6:8]+commandSplit[4][4:6], 16)
|
||||
|
||||
for i in range(numberOfBlocksOrArrow):
|
||||
tmpObj=self.getBlockOrArrowCommand()
|
||||
isBlock=tmpObj[1]
|
||||
returnData.append(tmpObj[0])
|
||||
|
||||
if returnData :
|
||||
finalData = []
|
||||
tmp = []
|
||||
for i in returnData:
|
||||
tmp = []
|
||||
for q in range(0, len(i), 4):
|
||||
low=int(i[q:q+2], 16)
|
||||
high=int(i[q+2:q+4], 16)
|
||||
if(high>0):
|
||||
val=low+255+high
|
||||
else:
|
||||
val=low
|
||||
tmp.append(val)
|
||||
finalData.append(tmp)
|
||||
tmp = []
|
||||
self.checkOnceAgain=True
|
||||
self._buffer=self.convert_to_class_object(finalData,isBlock)
|
||||
return "Data processing completed"
|
||||
else:
|
||||
self._buffer=[]
|
||||
|
||||
def convert_to_class_object(self,data,isBlock):
|
||||
tmp=[]
|
||||
for i in data:
|
||||
if(isBlock):
|
||||
obj = Block(i[0],i[1],i[2],i[3],i[4])
|
||||
else:
|
||||
obj = Arrow(i[0],i[1],i[2],i[3],i[4])
|
||||
tmp.append(obj)
|
||||
return tmp
|
||||
|
||||
def knock(self):
|
||||
'''Send a simple knock to the HuskyLens to ensure that you are connected and can communicate.'''
|
||||
self._write_cmd(commandHeaderAndAddress+"002c3c")
|
||||
return self._read_data()[3] == "2e"
|
||||
|
||||
def command_request_algorthim(self, alg):
|
||||
'''切换xx算法'''
|
||||
if alg in algorthimsByteID:
|
||||
cmd = commandHeaderAndAddress+"022d"+algorthimsByteID[alg]
|
||||
cmd += self._checksum(cmd)
|
||||
self._write_cmd(cmd)
|
||||
return self.processReturnData()
|
||||
else:
|
||||
print("INCORRECT ALGORITHIM NAME")
|
||||
|
||||
def command_request(self):
|
||||
'''请求一次数据 存入结果'''
|
||||
self._write_cmd(commandHeaderAndAddress+"002030")
|
||||
self.processReturnData()
|
||||
|
||||
def read_learned_id_count(self):
|
||||
'''从结果中获取 已学习ID总数'''
|
||||
return self._learned_number
|
||||
|
||||
def is_appear_direct(self,shape):
|
||||
'''从结果中获取 方块或箭头 是否在画面中'''
|
||||
if len(self._buffer) > 0:
|
||||
return self._buffer[0].type == shape
|
||||
|
||||
|
||||
def read_block_center_parameter_direct(self,shape):
|
||||
'''从结果中获取靠近中心 方块或箭头 的信息'''
|
||||
if len(self._buffer) > 0:
|
||||
if self._buffer[0].type == shape :
|
||||
return self._buffer[0]
|
||||
else :
|
||||
return False
|
||||
|
||||
def is_learned(self,get_id):
|
||||
'''从结果中获取获取IDx是否已学习'''
|
||||
if 0 < get_id < self._learned_number:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def is_appear(self,get_id,shape):
|
||||
'''从结果中获取获取IDx 方块或箭头 是否在画面中'''
|
||||
if len(self._buffer) > 0:
|
||||
for i in self._buffer :
|
||||
if i.id == get_id :
|
||||
return i.type == shape
|
||||
|
||||
def read_blocks_arrows_parameter(self,get_id,number,shape):
|
||||
'''从结果中获取获取IDx 第number个方块或箭头 的信息'''
|
||||
if len(self._buffer) > 0:
|
||||
id_list=[]
|
||||
for i in self._buffer :
|
||||
if i.id == get_id and i.type == shape:
|
||||
id_list.append(i)
|
||||
if number is None:
|
||||
return id_list[0]
|
||||
else:
|
||||
return id_list[number-1]
|
||||
|
||||
def read_count(self,get_id,shape):
|
||||
'''从结果中获取获取IDx 方块或箭头 的总数'''
|
||||
num=0
|
||||
if len(self._buffer) > 0:
|
||||
for i in self._buffer :
|
||||
if get_id is None and i.type == shape:
|
||||
num+=1
|
||||
if i.id == get_id and i.type == shape:
|
||||
num+=1
|
||||
return num
|
||||
|
||||
def read_blocks_arrows_parameter_direct(self,number,shape):
|
||||
'''从结果中获取获取第x个 方块或箭头 的信息'''
|
||||
if len(self._buffer) >= number :
|
||||
print(len(self._buffer))
|
||||
if self._buffer[number-1].type == shape :
|
||||
return self._buffer[number-1]
|
||||
|
||||
def command_request_learn_once(self,get_id):
|
||||
'''自动学习一次 IDx'''
|
||||
data = "{:04x}".format(get_id)
|
||||
part1=data[2:]
|
||||
part2=data[0:2]
|
||||
#reverse to correct endiness
|
||||
data=part1+part2
|
||||
dataLen = "{:02x}".format(len(data)//2)
|
||||
cmd = commandHeaderAndAddress+dataLen+"36"+data
|
||||
print("-----",cmd)
|
||||
cmd += self._checksum(cmd)
|
||||
self._write_cmd(cmd)
|
||||
|
||||
def command_request_forget(self):
|
||||
'''遗忘当前算法的所有学习数据'''
|
||||
self._write_cmd(commandHeaderAndAddress+"003747")
|
||||
|
||||
def command_request_customnames(self,name,get_id):
|
||||
'''设置当前算法 IDx 名字为 name'''
|
||||
nameDataSize = "{:02x}".format(len(name)+1)
|
||||
name = hexlify(name).decode()+"00"
|
||||
localId = "{:02x}".format(get_id)
|
||||
data = localId+nameDataSize+name
|
||||
dataLen = "{:02x}".format(len(data)//2)
|
||||
cmd = commandHeaderAndAddress+dataLen+"2f"+data
|
||||
cmd += self._checksum(cmd)
|
||||
self._write_cmd(cmd)
|
||||
|
||||
def command_request_custom_text(self,name,x,y):
|
||||
'''屏幕叠加显示文字name 在 xy'''
|
||||
name=hexlify(name).decode()
|
||||
nameDataSize = "{:02x}".format(len(name)//2)
|
||||
if x>255:
|
||||
x="ff"+"{:02x}".format(x%255)
|
||||
else:
|
||||
x="00"+"{:02x}".format(x)
|
||||
y="{:02x}".format(y)
|
||||
data = nameDataSize+x+y+name
|
||||
dataLen = "{:02x}".format(len(data)//2)
|
||||
cmd = commandHeaderAndAddress+dataLen+"34"+data
|
||||
cmd += self._checksum(cmd)
|
||||
self._write_cmd(cmd)
|
||||
|
||||
def command_request_clear_text(self):
|
||||
'''清除屏幕显示的文字'''
|
||||
self._write_cmd(commandHeaderAndAddress+"003545")
|
||||
|
||||
def command_request_photo(self):
|
||||
'''触发拍照保存到SD卡'''
|
||||
self._write_cmd(commandHeaderAndAddress+"003040")
|
||||
time.sleep(0.5)
|
||||
|
||||
def command_request_screenshot(self):
|
||||
'''触发截屏保存到SD卡'''
|
||||
self._write_cmd(commandHeaderAndAddress+"003949")
|
||||
time.sleep(0.5)
|
||||
|
||||
def command_request_save_model_to_SD_card(self,idVal):
|
||||
'''保存当前算法数据位SD卡 (0~4) 号模型'''
|
||||
idVal = "{:04x}".format(idVal)
|
||||
idVal = idVal[2:]+idVal[0:2]
|
||||
cmd = commandHeaderAndAddress+"0232"+idVal
|
||||
cmd += self._checksum(cmd)
|
||||
self._write_cmd(cmd)
|
||||
time.sleep(0.5)
|
||||
|
||||
def command_request_load_model_from_SD_card(self,idVal):
|
||||
'''加载当前算法数据位SD卡 (0~4) 号模型'''
|
||||
idVal = "{:04x}".format(idVal)
|
||||
idVal = idVal[2:]+idVal[0:2]
|
||||
cmd = commandHeaderAndAddress+"0233"+idVal
|
||||
cmd += self._checksum(cmd)
|
||||
self._write_cmd(cmd)
|
||||
time.sleep(0.5)
|
||||
69
mixly/boards/default/micropython/build/lib/hx720.py
Normal file
69
mixly/boards/default/micropython/build/lib/hx720.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""
|
||||
HX720/HX711
|
||||
|
||||
Micropython library for the HX720/HX711(Load Cell)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from machine import Pin
|
||||
from micropython import const
|
||||
|
||||
DATA_BITS = const(24)
|
||||
READY_TIMEOUT_SEC = const(500)
|
||||
|
||||
class HX720:
|
||||
def __init__(self, sck_pin, dat_pin, scale=500, pulse_obj=1):
|
||||
self._sck = Pin(sck_pin, Pin.OUT, value=0)
|
||||
self._dat = Pin(dat_pin, Pin.IN, Pin.PULL_UP)
|
||||
self._obj = min(max(pulse_obj, 1), 3)
|
||||
self.scale = scale
|
||||
self.tare()
|
||||
|
||||
def _wait(self):
|
||||
"""超时响应报错"""
|
||||
star = time.ticks_ms()
|
||||
while not self.is_ready():
|
||||
if time.ticks_diff(time.ticks_ms(), star) > READY_TIMEOUT_SEC:
|
||||
raise AttributeError("Cannot find a HX711/HX720")
|
||||
|
||||
def is_ready(self):
|
||||
"""检查是否有数据可以读取"""
|
||||
return self._dat.value() == 0
|
||||
|
||||
def set_scale(self, scale):
|
||||
"""设置比例因子"""
|
||||
self.scale = scale
|
||||
|
||||
def read_raw(self):
|
||||
"""读取传感器的原始数据"""
|
||||
if not self.is_ready():
|
||||
self._wait()
|
||||
raw_data = 0
|
||||
for _ in range(DATA_BITS):
|
||||
self._sck.value(1)
|
||||
self._sck.value(0)
|
||||
raw_data = raw_data << 1 | self._dat.value()
|
||||
|
||||
# 根据脉冲功能设置多读几次
|
||||
for _ in range(self._obj):
|
||||
self._sck.value(1)
|
||||
self._sck.value(0)
|
||||
|
||||
return raw_data if raw_data < (1 << (DATA_BITS - 1)) else raw_data - (1 << DATA_BITS)
|
||||
|
||||
def tare(self, times=10):
|
||||
"""清零传感器"""
|
||||
_values = []
|
||||
for _ in range(max(times, 5)):
|
||||
_values.append(self.read_raw())
|
||||
_values = sorted(_values)[2: -2]
|
||||
self.offset = sum(_values) / len(_values)
|
||||
|
||||
def read_weight(self, times=5):
|
||||
"""读取重量数据,返回去掉偏移量的平均值"""
|
||||
_values = []
|
||||
for _ in range(max(times, 3)):
|
||||
_values.append(self.read_raw())
|
||||
_values = sorted(_values)[1: -1]
|
||||
return round((sum(_values) / len(_values)- self.offset) / self.scale, 2)
|
||||
280
mixly/boards/default/micropython/build/lib/i2cdevice.py
Normal file
280
mixly/boards/default/micropython/build/lib/i2cdevice.py
Normal file
@@ -0,0 +1,280 @@
|
||||
"""
|
||||
I2C_Device
|
||||
|
||||
Micropython library for the I2C communication Device(TD)
|
||||
=======================================================
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import random
|
||||
from machine import SoftI2C
|
||||
|
||||
def _u2s(value, n=8):
|
||||
return value if value < (1 << (n-1)) else value - (1 << n)
|
||||
|
||||
'''i2c-Inheritance'''
|
||||
class I2C_device(SoftI2C):
|
||||
|
||||
CRC8_Table =b'\x00^\xbc\xe2a?\xdd\x83\xc2\x9c~ \xa3\xfd\x1fA\x9d\xc3!\x7f\xfc\xa2@\x1e_\x01\xe3\xbd>`\x82\xdc#}\x9f\xc1B\x1c\xfe\xa0\xe1\xbf]\x03\x80\xde<b\xbe\xe0\x02\\\xdf\x81c=|"\xc0\x9e\x1dC\xa1\xffF\x18\xfa\xa4\'y\x9b\xc5\x84\xda8f\xe5\xbbY\x07\xdb\x85g9\xba\xe4\x06X\x19G\xa5\xfbx&\xc4\x9ae;\xd9\x87\x04Z\xb8\xe6\xa7\xf9\x1bE\xc6\x98z$\xf8\xa6D\x1a\x99\xc7%{:d\x86\xd8[\x05\xe7\xb9\x8c\xd20n\xed\xb3Q\x0fN\x10\xf2\xac/q\x93\xcd\x11O\xad\xf3p.\xcc\x92\xd3\x8do1\xb2\xec\x0eP\xaf\xf1\x13M\xce\x90r,m3\xd1\x8f\x0cR\xb0\xee2l\x8e\xd0S\r\xef\xb1\xf0\xaeL\x12\x91\xcf-s\xca\x94v(\xab\xf5\x17I\x08V\xb4\xeai7\xd5\x8bW\t\xeb\xb56h\x8a\xd4\x95\xcb)w\xf4\xaaH\x16\xe9\xb7U\x0b\x88\xd64j+u\x97\xc9J\x14\xf6\xa8t*\xc8\x96\x15K\xa9\xf7\xb6\xe8\nT\xd7\x89k5'
|
||||
|
||||
def _crc8(self, buf):
|
||||
_sum = 0
|
||||
for i in range(0, len(buf)):
|
||||
_sum = self.CRC8_Table[_sum ^ buf[i]]
|
||||
return _sum
|
||||
|
||||
def read_device(self, addr, cmd, nbytes=1):
|
||||
buf = self.readfrom_mem(addr, cmd, nbytes+2)
|
||||
if self._crc8(buf[:-1]) == buf[-1]:
|
||||
return buf[1] if nbytes<=1 else buf[1:-1]
|
||||
|
||||
def write_device(self, addr, cmd, buf=0):
|
||||
buf = buf.to_bytes(1, 'little') if type(buf) is int else buf
|
||||
buf = bytearray([cmd, random.randint(0, 255)]) + buf
|
||||
crc8 = self._crc8(buf).to_bytes(1, 'little')
|
||||
self.writeto(addr, buf + crc8)
|
||||
if crc8 == self.readfrom(addr, 1):
|
||||
return True
|
||||
|
||||
'''Fundamentals of Sensors'''
|
||||
class Base:
|
||||
def __init__(self, i2c_bus):
|
||||
self._i2c = i2c_bus
|
||||
|
||||
def addr_set(self, old=0, new=0):
|
||||
try:
|
||||
self._i2c.write_device(self._addrs[old], 0x04, bytearray([self._addrs[old], self._addrs[new]]))
|
||||
except Exception as e:
|
||||
print("Warning: No serial number can be changed or", e)
|
||||
|
||||
def addr_get(self):
|
||||
_addred = []
|
||||
for add in self._i2c.scan():
|
||||
if add in self._addrs:
|
||||
_addred.append(self._addrs.index(add))
|
||||
return tuple(_addred)
|
||||
|
||||
'''Motor'''
|
||||
class Motor(Base):
|
||||
_addrs = [0x30, 0x31, 0x32, 0x33]
|
||||
|
||||
def run(self, naddr=0, speed=None):
|
||||
'''普票电机参数 speed: 速度-100~100%, None返回速度值'''
|
||||
try:
|
||||
if speed is None:
|
||||
return _u2s(self._i2c.read_device(self._addrs[naddr], 0x10))
|
||||
else:
|
||||
speed = max(min(speed, 100), -100)
|
||||
self._i2c.write_device(self._addrs[naddr], 0xA0, speed)
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Motor device", e)
|
||||
|
||||
'''Traffic light'''
|
||||
class Traffic_LED(Base):
|
||||
_addrs = [0x48, 0x49, 0x4A, 0x4B]
|
||||
|
||||
def led(self, naddr=0, num=0, value=0):
|
||||
'''交通灯参数 value: 0,全灭 1,长亮 -1,闪烁(1hz)'''
|
||||
try:
|
||||
if value == 0:
|
||||
self._i2c.write_device(self._addrs[naddr], 0xA0, 0x00)
|
||||
elif value == 1:
|
||||
self._i2c.write_device(self._addrs[naddr], 0xA0, 0x04 >> num)
|
||||
elif value == -1:
|
||||
self._i2c.write_device(self._addrs[naddr], 0xA0, 0x40 >> num)
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Traffic lights", e)
|
||||
|
||||
'''LED'''
|
||||
class LED(Base):
|
||||
|
||||
def brightness(self, naddr=0, value=None):
|
||||
'''LED灯参数 value: 亮度0~100%, None返回亮度值'''
|
||||
try:
|
||||
if value is None:
|
||||
return self._i2c.read_device(self._addrs[naddr], 0x10)
|
||||
else:
|
||||
value = max(min(value, 100), 0)
|
||||
self._i2c.write_device(self._addrs[naddr], 0xA0, value)
|
||||
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a LED device", e)
|
||||
|
||||
class W_LED(LED):
|
||||
_addrs = [0x38, 0x39, 0x3A, 0x3B]
|
||||
|
||||
class R_LED(LED):
|
||||
_addrs = [0x3C, 0x3D, 0x3E, 0x3F]
|
||||
|
||||
class Y_LED(LED):
|
||||
_addrs = [0x40, 0x41, 0x42, 0x43]
|
||||
|
||||
class G_LED(LED):
|
||||
_addrs = [0x44, 0x45, 0x46, 0x47]
|
||||
|
||||
class B_LED(LED):
|
||||
_addrs = [0x78, 0x79, 0x7A, 0x7B]
|
||||
|
||||
'''button*5'''
|
||||
class Buttonx5(Base):
|
||||
_addrs = [0x68, 0x69, 0x6A, 0x6B]
|
||||
|
||||
def value(self, naddr=0):
|
||||
'''十字按键返回 (上,下,左,右,中)/bool'''
|
||||
try:
|
||||
flag = self._i2c.read_device(self._addrs[naddr], 0x10)
|
||||
return bool(flag >> 4 & 1), bool(flag >> 3 & 1), bool(flag >> 2 & 1), bool(flag >> 1 & 1), bool(flag & 1)
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Button sensor", e)
|
||||
|
||||
'''button*1'''
|
||||
class Button(Base):
|
||||
_addrs = [0x54, 0x55, 0x56, 0x57]
|
||||
|
||||
def value(self, naddr=0):
|
||||
'''触碰传感器返回 数值/bool'''
|
||||
try:
|
||||
return bool(self._i2c.read_device(self._addrs[naddr], 0x10))
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Touch sensor", e)
|
||||
|
||||
'''Infrared sensor'''
|
||||
class Infrared(Base):
|
||||
_addrs = [0x6C, 0x6D, 0x6E, 0x6F]
|
||||
|
||||
def value(self, naddr=0):
|
||||
'''红外接近返回 数值0~100%'''
|
||||
try:
|
||||
return self._i2c.read_device(self._addrs[naddr], 0x10)
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Infrared sensor", e)
|
||||
|
||||
'''ultrasonic sensor'''
|
||||
class Sonar(Base):
|
||||
_addrs = [0x24, 0x25, 0x26, 0x27]
|
||||
_state = 0x00
|
||||
def value(self, naddr=0):
|
||||
'''超声波测距返回 距离数值cm'''
|
||||
try:
|
||||
value = self._i2c.read_device(self._addrs[naddr], 0x10, 2)
|
||||
return value[0] << 8 | value[1]
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Ultrasonic sensor", e)
|
||||
|
||||
def led(self, naddr=0, num=0, value=0):
|
||||
'''超声波指示灯参数 num:序号0~3,value:0灭,1亮,-1反转 '''
|
||||
try:
|
||||
if value > 0:
|
||||
self._state |= 1 << num
|
||||
elif value < 0:
|
||||
self._state ^= 1 << num
|
||||
else:
|
||||
self._state &= ~ (1 << num)
|
||||
self._i2c.write_device(self._addrs[naddr], 0xA0, bytearray([self._state & 0xff, 0x00]))
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Ultrasonic sensor", e)
|
||||
|
||||
'''Potentiometer'''
|
||||
class Dimmer(Base):
|
||||
_addrs = [0x2C, 0x2D, 0x2E, 0x2F]
|
||||
|
||||
def value(self, naddr=0):
|
||||
'''旋钮传感器返回 数值0~100%'''
|
||||
try:
|
||||
return self._i2c.read_device(self._addrs[naddr], 0x10)
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Potentiometer", e)
|
||||
|
||||
'''Color sensor'''
|
||||
class Color_ID(Base):
|
||||
_id = ('Black', 'Violet', 'Unknown', 'Blue', 'Cyan', 'Green', 'Unknown', 'Yellow', 'Unknown', 'Red', 'White', 'Unknown')
|
||||
_addrs = [0x20, 0x21, 0x22, 0x23]
|
||||
|
||||
def recognition(self, naddr=0):
|
||||
'''颜色识别返回 (颜色名,(R,G,B),环境亮度0~100,反射亮度0~100)'''
|
||||
try:
|
||||
color = self._i2c.read_device(self._addrs[naddr], 0x10, 6)
|
||||
return self._id[min(color[0],11)], (color[1],color[2],color[3]), color[4], color[5]
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Color sensor", e)
|
||||
|
||||
'''Laser Sensor'''
|
||||
class TOF(Base):
|
||||
_addrs = [0x5C, 0x5D, 0x5E, 0x5F]
|
||||
|
||||
def value(self, naddr=0):
|
||||
'''激光测距传感器返回 数值cm'''
|
||||
try:
|
||||
flag = self._i2c.read_device(self._addrs[naddr], 0x10, 2)
|
||||
return (flag[0] << 8 | flag[1]) / 100
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Laser Sensor", e)
|
||||
|
||||
def enable(self, naddr=0, en=True):
|
||||
'''激光测距传感器 en:0关闭,1打开'''
|
||||
try:
|
||||
self._i2c.write_device(self._addrs[naddr], 0xA0, int(en) & 0x01)
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Laser Sensor", e)
|
||||
|
||||
'''Servo Motor'''
|
||||
class Motor_servo(Base):
|
||||
_addrs = [0x60, 0x61, 0x62, 0x63]
|
||||
_mstop = [0, 0, 0, 0]
|
||||
|
||||
def stop_mode(self, naddr=0, mode=0):
|
||||
'''电机停止模式 mode:0,保持位置 1,惯性滑行 2,阻力制动'''
|
||||
self._mstop[naddr] = mode
|
||||
|
||||
def _write(self, naddr=0, mode=0, value=0, direction=0, angle=0, origin=0, keep=0, select=0):
|
||||
'''寄存器参数设置'''
|
||||
try:
|
||||
_bytes1 = direction<<6 | mode<<5 | select<<4 | origin<<3 | keep<<2 | self._mstop[naddr]
|
||||
_bytes2 = max(min(value, 100), 0)
|
||||
_bytes3 = angle & 0xFF
|
||||
_bytes4 = angle>>8 & 0xFF
|
||||
_bytes5 = angle>>16 & 0xFF
|
||||
self._i2c.write_device(self._addrs[naddr], 0xA0, bytearray([_bytes1, _bytes2, _bytes3, _bytes4, _bytes5]))
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Servo Motor", e)
|
||||
|
||||
def absolute_run(self, naddr=0, mode=0, value=50, direction=0, angle=0):
|
||||
''' 绝对角度运行模式(类舵机)
|
||||
运行模式mode 0:速度模式,1:功率模式
|
||||
模式数值value 0~100%
|
||||
转向设置direction 0:顺时针,1:最短路径,2:逆时针
|
||||
旋转角度angle 0~360°
|
||||
'''
|
||||
self._write(naddr=naddr, mode=mode, value=value, direction=direction, angle=angle, select=0)
|
||||
|
||||
def relative_run(self, naddr=0, mode=0, value=50, angle=0):
|
||||
''' 相对角度运行模式(类编码电机)
|
||||
运行模式mode 0:速度模式,1:功率模式
|
||||
模式数值value 0~100%
|
||||
旋转角度angle -8388607~8388607°
|
||||
'''
|
||||
self._write(naddr=naddr, mode=mode, value=value, angle=angle, select=1)
|
||||
|
||||
def relative_origin(self, naddr=0):
|
||||
'''当前位置设置为原点'''
|
||||
self._write(naddr=naddr, origin=1, select=1)
|
||||
|
||||
def relative_continue(self, naddr=0, mode=0, value=50, direction=0):
|
||||
''' 相对角度运行模式(类普通电机)
|
||||
运行模式mode 0:速度模式,1:功率模式
|
||||
模式数值value 0~100%
|
||||
转向设置direction 0:顺时针,2:逆时针
|
||||
'''
|
||||
self._write(naddr=naddr, mode=mode, value=value, direction=direction, keep=1, select=1)
|
||||
|
||||
def stop(self, naddr=0):
|
||||
'''电机停止'''
|
||||
self._write(naddr=naddr, keep=1)
|
||||
|
||||
def state(self,naddr=0):
|
||||
'''运行状态返回 (功率, 速度, 绝对角度, 相对角度, 是否堵住, 是否转完) '''
|
||||
try:
|
||||
_buf = self._i2c.read_device(self._addrs[naddr], 0x10, 7)
|
||||
return _u2s(_buf[0]), _u2s(_buf[1]), (_buf[2] & 0x01)<<8 | _buf[3], _u2s((_buf[4]<<16 | _buf[5]<<8 | _buf[6]),24), bool(_buf[2] & 0x40), bool(_buf[2] & 0x80)
|
||||
except Exception as e:
|
||||
raise RuntimeError("Cannot find a Servo Motor", e)
|
||||
79
mixly/boards/default/micropython/build/lib/i2clcd.py
Normal file
79
mixly/boards/default/micropython/build/lib/i2clcd.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""
|
||||
LCD1602、LCD2004_I2C
|
||||
|
||||
Micropython library for the I2C(LCD1602、LCD2004)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20221117
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
from time import sleep_ms
|
||||
from micropython import const
|
||||
|
||||
LCD_DAT = const(0x01) # Mode - Sending data
|
||||
LCD_CMD = const(0x00) # Mode - Sending command
|
||||
LCD_LINES = (0x80, 0xC0, 0x94, 0xD4)
|
||||
|
||||
class LCD():
|
||||
def __init__(self, i2c_bus, i2c_addr=0x27, lcd_width=16):
|
||||
self._device = i2c_bus
|
||||
self._address = i2c_addr
|
||||
self._lcd_width = lcd_width
|
||||
self._backlight = True
|
||||
self._last_data = 0x00
|
||||
|
||||
for i in [0x30, 0x30, 0x30,0x20]:
|
||||
self._i2c_write(i)
|
||||
sleep_ms(1)
|
||||
for i in [0x28, 0x0C, 0x06]:
|
||||
self.write_byte(i , LCD_CMD)
|
||||
self.clear()
|
||||
|
||||
def _i2c_write(self, data , pulse_en=True):
|
||||
"""write one byte to I2C bus"""
|
||||
self._last_data = data
|
||||
self._device.writeto(self._address,data.to_bytes(1, 'little'))
|
||||
sleep_ms(0)
|
||||
if pulse_en :
|
||||
self._device.writeto(self._address,(data | 0b00000100).to_bytes(1, 'little'))
|
||||
sleep_ms(0)
|
||||
self._device.writeto(self._address,(data & ~0b00000100).to_bytes(1, 'little'))
|
||||
sleep_ms(0)
|
||||
|
||||
def write_byte(self, data, mode):
|
||||
"""write one byte to LCD"""
|
||||
data_H = (data & 0xF0) | self._backlight * 0x08 | mode
|
||||
data_L = ((data << 4) & 0xF0) | self._backlight * 0x08 | mode
|
||||
self._i2c_write(data_H)
|
||||
self._i2c_write(data_L)
|
||||
|
||||
def clear(self):
|
||||
"""Clear the display and reset the cursor position"""
|
||||
self.write_byte(0x01, LCD_CMD)
|
||||
sleep_ms(1)
|
||||
|
||||
def backlight(self, on_off):
|
||||
""" Set whether the LCD backlight is on or off"""
|
||||
self._backlight = on_off & 0x01
|
||||
i2c_data = (self._last_data & 0xF7) + self._backlight * 0x08
|
||||
self._i2c_write(i2c_data,pulse_en=False)
|
||||
|
||||
def shows(self, text, line=0, column=0, center=False):
|
||||
'''Character display'''
|
||||
text = str(text).encode('ascii')
|
||||
column=(self._lcd_width-len(text))//2 if center else column
|
||||
self.write_byte(LCD_LINES[line] + column, LCD_CMD)
|
||||
for b in text:
|
||||
self.write_byte(0x0C+0*0x02+0*0x01, LCD_CMD)
|
||||
self.write_byte(b, LCD_DAT)
|
||||
|
||||
def print(self, text, line=0, column=0, delay=500):
|
||||
'''Print Effect Character Display'''
|
||||
text = str(text).encode('ascii')
|
||||
self.write_byte(LCD_LINES[line] + column, LCD_CMD)
|
||||
for b in text:
|
||||
self.write_byte(0x0C+1*0x02+1*0x01, LCD_CMD)
|
||||
sleep_ms(delay)
|
||||
self.write_byte(b, LCD_DAT)
|
||||
sleep_ms(delay)
|
||||
94
mixly/boards/default/micropython/build/lib/icm42670.py
Normal file
94
mixly/boards/default/micropython/build/lib/icm42670.py
Normal file
@@ -0,0 +1,94 @@
|
||||
"""
|
||||
ICM42670P
|
||||
|
||||
Micropython library for the ICM42670P(Accelerometer+Gyroscope)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20220716
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
ICM42670_REG_DEVICE_ID = const(0x00)
|
||||
ICM42670_REG_RESET = const(0x02)
|
||||
ICM42670_REG_DATA = const(0x09)
|
||||
ICM42670_REG_PWR_MGMT0 = const(0x1F)
|
||||
ICM42670_REG_GYRO_CONFIG0 = const(0x20)
|
||||
ICM42670_REG_ACCEL_CONFIG0 = const(0x21)
|
||||
ICM42670_REG_APEX_DATA0 = const(0x31)
|
||||
ICM42670_REG_WHO_AM_I = const(0x75)
|
||||
|
||||
AccRange_16g = 0
|
||||
AccRange_8g = 1
|
||||
AccRange_4g = 2
|
||||
AccRange_2g = 3
|
||||
|
||||
GyrRange_2000dps = 0
|
||||
GyrRange_1000dps = 1
|
||||
GyrRange_500dps = 2
|
||||
GyrRange_250dps = 3
|
||||
|
||||
Acc_Gyr_Odr_1600Hz = 0x05
|
||||
Acc_Gyr_Odr_800Hz = 0x06
|
||||
Acc_Gyr_Odr_400Hz = 0x07
|
||||
Acc_Gyr_Odr_200Hz = 0x08
|
||||
Acc_Gyr_Odr_100Hz = 0x09
|
||||
Acc_Gyr_Odr_50Hz = 0x0A
|
||||
Acc_Gyr_Odr_25Hz = 0x0B
|
||||
Acc_Gyr_Odr_12_5Hz = 0x0C
|
||||
|
||||
class ICM42670:
|
||||
def __init__(self, i2c_bus, addr=0x68, AccRange=AccRange_16g, GyrRange=GyrRange_2000dps, Acc_Gyr_Odr=Acc_Gyr_Odr_100Hz):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
if self._chip_id() != 0x67:
|
||||
raise AttributeError("Cannot find a ICM42670")
|
||||
|
||||
self._wreg(ICM42670_REG_RESET,0x10) #Software reset enabled
|
||||
time.sleep(0.1)
|
||||
self._wreg(ICM42670_REG_GYRO_CONFIG0,(GyrRange << 4) | Acc_Gyr_Odr) #Gyr-500HZ/2000dps
|
||||
self._wreg(ICM42670_REG_ACCEL_CONFIG0,(AccRange << 4) | Acc_Gyr_Odr) #ACC-100HZ/16G
|
||||
self._wreg(ICM42670_REG_PWR_MGMT0,0x1E)
|
||||
time.sleep(0.1)
|
||||
self.acc_lsb_div= 2 ** (11 + AccRange)
|
||||
self.gyr_lsb_div= 2 ** (14 + GyrRange)
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg,nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _chip_id(self):
|
||||
return self._rreg(ICM42670_REG_WHO_AM_I)
|
||||
|
||||
def u2s(self,n):
|
||||
return n if n < (1 << 15) else n - (1 << 16)
|
||||
|
||||
def getdata(self):
|
||||
_buffer=self._rreg(ICM42670_REG_DATA,14)
|
||||
tmp= float(self.u2s(_buffer[0]<<8|_buffer[1]))/128+25
|
||||
acc_x=float(self.u2s(_buffer[2]<<8|_buffer[3]))/self.acc_lsb_div
|
||||
acc_y=float(self.u2s(_buffer[4]<<8|_buffer[5]))/self.acc_lsb_div
|
||||
acc_z=float(self.u2s(_buffer[6]<<8|_buffer[7]))/self.acc_lsb_div
|
||||
gyr_x=float(self.u2s(_buffer[8]<<8|_buffer[9]))/self.gyr_lsb_div
|
||||
gyr_y=float(self.u2s(_buffer[10]<<8|_buffer[11]))/self.gyr_lsb_div
|
||||
gyr_z=float(self.u2s(_buffer[12]<<8|_buffer[13]))/self.gyr_lsb_div
|
||||
return (acc_x,acc_y,acc_z),(gyr_x,gyr_y,gyr_z),round(tmp,2)
|
||||
|
||||
def accelerometer(self):
|
||||
return self.getdata()[0]
|
||||
|
||||
def strength(self):
|
||||
from math import sqrt
|
||||
return sqrt(self.accelerometer()[0]**2+self.accelerometer()[1]**2+self.accelerometer()[2]**2)
|
||||
|
||||
def gyroscope(self):
|
||||
return self.getdata()[1]
|
||||
|
||||
def temperature(self):
|
||||
return self.getdata()[2]
|
||||
87
mixly/boards/default/micropython/build/lib/image.py
Normal file
87
mixly/boards/default/micropython/build/lib/image.py
Normal file
@@ -0,0 +1,87 @@
|
||||
"""
|
||||
Iamge
|
||||
|
||||
MicroPython library for the Iamge(jpeg C module)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import gc
|
||||
import urequests
|
||||
from base64 import b64encode
|
||||
from jpeg import Encoder, Decoder
|
||||
|
||||
class IMG:
|
||||
def __init__(self, image, width, height):
|
||||
self.image = image
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.format = "RGB565"
|
||||
|
||||
class Image:
|
||||
def save(self, img, path="mixly.jpg", **kwargs):
|
||||
'''quality(1-100), rotation (0, 90, 180, 270)'''
|
||||
_encoder = Encoder(pixel_format="RGB565_BE", width=img.width, height=img.height, **kwargs)
|
||||
_jpeg = _encoder.encode(img.image)
|
||||
del _encoder
|
||||
gc.collect()
|
||||
if isinstance(path, str):
|
||||
with open(path, 'wb') as f:
|
||||
f.write(_jpeg)
|
||||
else:
|
||||
return _jpeg
|
||||
|
||||
def open(self, path="mixly.jpg", scale_width=None, scale_height=None, tft_width=240, tft_height=240, **kwargs):
|
||||
'''rotation (0, 90, 180, 270), clipper_width, clipper_height'''
|
||||
with open(path, "rb") as f:
|
||||
_jpeg = f.read()
|
||||
return self._jpg_decoder(_jpeg, scale_width, scale_height, tft_width, tft_height, **kwargs)
|
||||
|
||||
def convert(self, img, formats=0, **kwargs):
|
||||
if formats == 0:
|
||||
return self.save(img, None, **kwargs)
|
||||
elif formats == 1:
|
||||
return b'data:image/jpg;base64,' + b64encode(self.save(img, None, **kwargs))
|
||||
|
||||
def download(self, url, path=None, scale_width=None, scale_height=None, tft_width=240, tft_height=240, block=1024, **kwargs):
|
||||
'''rotation (0, 90, 180, 270), clipper_width, clipper_height'''
|
||||
response = urequests.get(url, stream=True)
|
||||
if path is None:
|
||||
_image = self._jpg_decoder(response.raw.read(), scale_width, scale_height, tft_width, tft_height, **kwargs)
|
||||
response.close()
|
||||
return _image
|
||||
else:
|
||||
with open(path, 'wb') as f:
|
||||
while True:
|
||||
_data = response.raw.read(block)
|
||||
if not _data:
|
||||
break
|
||||
else:
|
||||
f.write(_data)
|
||||
response.close()
|
||||
|
||||
def _jpg_decoder(self, jpg, scale_width, scale_height, tft_width, tft_height, **kwargs):
|
||||
'''Automatically zoom based on the screen'''
|
||||
if scale_width is None or scale_height is None:
|
||||
_width = tft_width
|
||||
_height = tft_height
|
||||
for i in range(min(len(jpg), 1024)):
|
||||
if jpg[i] == 0xFF and (jpg[i + 1] & 0xF0) == 0xC0:
|
||||
if jpg[i + 1] not in [0xC4, 0xC8, 0xCC]:
|
||||
_width = jpg[i + 7] << 8 | jpg[i + 8]
|
||||
_height = jpg[i + 5] << 8| jpg[i + 6]
|
||||
break
|
||||
if _width > tft_width or _height > tft_height:
|
||||
_scale = max(_width / tft_width, _height / tft_height) * 8
|
||||
_decoder = Decoder(pixel_format="RGB565_BE", scale_width=round(_width / _scale) * 8, scale_height=round(_height / _scale) * 8, **kwargs)
|
||||
else:
|
||||
_decoder = Decoder(pixel_format="RGB565_BE", **kwargs)
|
||||
else:
|
||||
_decoder = Decoder(pixel_format="RGB565_BE", scale_width=scale_width // 8 * 8, scale_height=scale_height // 8 * 8, **kwargs)
|
||||
_info = _decoder.get_img_info(jpg)
|
||||
_image = IMG(_decoder.decode(jpg), _info[0], _info[1])
|
||||
del _decoder, jpg
|
||||
gc.collect()
|
||||
return _image
|
||||
|
||||
#图像处理
|
||||
Image = Image()
|
||||
@@ -0,0 +1,18 @@
|
||||
#Take the picture bytes in informatio_picture.py
|
||||
#--dahanzimin From the Mixly Team
|
||||
|
||||
Accept=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00p\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x01\xa7\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x03y\x80\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x02~`\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x04\xff0\x00\x7f\x00\x00\x00\x00\x00\x00\x00\t\xff\xec\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x1b\xff\xf6\x00\x7f\x00\x00\x00\x00\x00\x00\x007\xff\xfd\x80\x7f\x00\x00\x00\x00\x00\x00\x00o\xff\xff\x80\x7f\x00\x00\x00\x00\x00\x00\x00_\xff\xff\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x9f\xff\xfe\x00\x7f\x00\x00\x00\x00\x00\x00\x01\xbf\xff\xfc\x00\x7f\x00\x00\x00\x00\x00\x00\x03\x7f\xff\xf8\x00\x7f\x00\x00\x00\x00\x00\x00\x06\xff\xff\xf0\x00\x7f\x00\x00\x00\x00\x00\x00\x05\xff\xff\xe0\x00\x7f\x00\x00\x00\x00\x00\x00\x0b\xff\xff\xc0\x00\x7f\x00\x00\x00\x00\x00\x00\x17\xff\xff\x80\x00\x7f\x00\x00\x00\x00\x00\x007\xff\xfe\x00\x00\x7f\x00\x00\x00\x00\x00\x00o\xff\xfc\x00\x00\x7f\x00\x00\x00\x00\x00\x00_\xff\xf8\x00\x00\x7f\x00\x00\x00\x00\x00\x00\xbf\xff\xf0\x00\x00\x7f\x00\x00\x00\x00\x00\x01\x7f\xff\xe0\x00\x00\x7f\x00\x00\x00\x00\x00\x03\x7f\xff\xc0\x00\x00\x7f\x00\x00\x00\x00\x00\x07\xff\xff\x80\x00\x00\x7f\x00\x00\x00\x00\x00\r\xff\xff\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0b\xff\xfe\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x7f\x00\x00\x00\x00\x00/\xff\xf8\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x7f\xff\xf0\x00\x00\x00\x7f\x00\x00\x01\xc0\x00\xff\xff\xe0\x00\x00\x00\x7f\x00\x00\x1e@\x00\xff\xff\xc0\x00\x00\x00\x7f\x00\x01\xeb \x01\xff\xff\x80\x00\x00\x00\x7f\x00\x1e\xff\xa0\x03\xff\xff\x00\x00\x00\x00\x7f\x00w\xff\xb0\x07\xff\xfe\x00\x00\x00\x00\x7f\x00?\xff\x90\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x1f\xff\xd0\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x1f\xff\xf8\x1f\xff\xf0\x00\x00\x00\x00\x7f\x00\x0f\xff\xe8?\xff\xe0\x00\x00\x00\x00\x7f\x00\x07\xff\xf8\x7f\xff\xc0\x00\x00\x00\x00\x7f\x00\x03\xff\xf4\xff\xff\x80\x00\x00\x00\x00\x7f\x00\x03\xff\xfd\xff\xff\x00\x00\x00\x00\x00\x7f\x00\x01\xff\xff\xff\xfe\x00\x00\x00\x00\x00\x7f\x00\x00\xff\xff\xff\xfc\x00\x00\x00\x00\x00\x7f\x00\x00\x7f\xff\xff\xf8\x00\x00\x00\x00\x00\x7f\x00\x00\x7f\xff\xff\xf0\x00\x00\x00\x00\x00\x7f\x00\x00?\xff\xff\xe0\x00\x00\x00\x00\x00\x7f\x00\x00\x1f\xff\xff\xc0\x00\x00\x00\x00\x00\x7f\x00\x00\x0f\xff\xff\x80\x00\x00\x00\x00\x00\x7f\x00\x00\x07\xff\xff\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x07\xff\xfe\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x03\xff\xf8\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x01\xff\xf0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\xff\xe0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x7f\x80\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00?\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Backward=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0b\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xf7\xfe\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xfdW\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\xff\xff\xf2\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\xff\xff\xe4\x00\x00\x00\x7f\x00\x00\x00\x0f\xff\xff\xff\xe8\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\xd8\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xff\xb0\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xff\xa0\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xff@\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\xff\xfe\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\xff\xfd\x00\x00\x00\x00\x7f\x00\x00\x00\x00?\xff\xfe\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfe\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x07\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xf0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x7f\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00?\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00>\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Decline=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x000\x00\x00\x00\x02\x00\x00\x00\x7f\x00\x00\x00x\x00\x00\x00\x05\x00\x00\x00\x7f\x00\x00\x00\xfc\x00\x00\x00\x0f\x80\x00\x00\x7f\x00\x00\x01\xfe\x00\x00\x00\x17\xc0\x00\x00\x7f\x00\x00\x03\xff\x00\x00\x00?\xa0\x00\x00\x7f\x00\x00\x07\xff\x80\x00\x00_\xf0\x00\x00\x7f\x00\x00\x0f\xff\xc0\x00\x00\xff\xe8\x00\x00\x7f\x00\x00\x1f\xff\xe0\x00\x01\x7f\xfc\x00\x00\x7f\x00\x00?\xff\xf0\x00\x03\xff\xfa\x00\x00\x7f\x00\x00\x7f\xff\xf8\x00\x05\xff\xff\x00\x00\x7f\x00\x00\xff\xff\xfc\x00\x0f\xff\xfe\x80\x00\x7f\x00\x01\xff\xff\xfe\x00\x17\xff\xff\xc0\x00\x7f\x00\x01\xff\xff\xff\x00?\xff\xff\xc0\x00\x7f\x00\x00\xff\xff\xff\x80_\xff\xff\x80\x00\x7f\x00\x00\x7f\xff\xff\xc0\xff\xff\xff\x00\x00\x7f\x00\x00?\xff\xff\xe1\x7f\xff\xfe\x00\x00\x7f\x00\x00\x1f\xff\xff\xf3\xff\xff\xfc\x00\x00\x7f\x00\x00\x0f\xff\xff\xfd\xff\xff\xf8\x00\x00\x7f\x00\x00\x07\xff\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\x03\xff\xff\xff\xff\xff\xe0\x00\x00\x7f\x00\x00\x01\xff\xff\xff\xff\xff\xc0\x00\x00\x7f\x00\x00\x00\xff\xff\xff\xff\xff\x80\x00\x00\x7f\x00\x00\x00\x7f\xff\xff\xff\xff\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xfe\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\xff\xff\xfc\x00\x00\x00\x7f\x00\x00\x00\x0f\xff\xff\xff\xf8\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\xf0\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xff\xe0\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xff\xe0\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xff\xf0\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\xf8\x00\x00\x00\x7f\x00\x00\x00\x0b\xff\xff\xff\xfc\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\xff\xff\xfe\x00\x00\x00\x7f\x00\x00\x00/\xff\xff\xff\xff\x00\x00\x00\x7f\x00\x00\x00\x7f\xff\xff\xff\xff\x80\x00\x00\x7f\x00\x00\x00\xbf\xff\xff\xff\xff\xc0\x00\x00\x7f\x00\x00\x01\xff\xff\xff\xff\xff\xe0\x00\x00\x7f\x00\x00\x02\xff\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\x07\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\x0b\xff\xff\xf7\xff\xff\xfc\x00\x00\x7f\x00\x00\x1f\xff\xff\xe3\xff\xff\xfe\x00\x00\x7f\x00\x00/\xff\xff\xc1\xff\xff\xff\x00\x00\x7f\x00\x00\x7f\xff\xff\x80\xff\xff\xff\x80\x00\x7f\x00\x00\xbf\xff\xff\x00\x7f\xff\xff\xc0\x00\x7f\x00\x01\xff\xff\xfe\x00?\xff\xff\xc0\x00\x7f\x00\x00\xff\xff\xfc\x00\x1f\xff\xff\xc0\x00\x7f\x00\x00\x7f\xff\xf8\x00\x0f\xff\xff\x80\x00\x7f\x00\x00?\xff\xf0\x00\x07\xff\xff\x00\x00\x7f\x00\x00\x1f\xff\xe0\x00\x03\xff\xfe\x00\x00\x7f\x00\x00\x0f\xff\xc0\x00\x01\xff\xfc\x00\x00\x7f\x00\x00\x07\xff\x80\x00\x00\xff\xf8\x00\x00\x7f\x00\x00\x03\xff\x00\x00\x00\x7f\xf0\x00\x00\x7f\x00\x00\x01\xfe\x00\x00\x00?\xe0\x00\x00\x7f\x00\x00\x00\xfc\x00\x00\x00\x1f\xc0\x00\x00\x7f\x00\x00\x00x\x00\x00\x00\x0f\x80\x00\x00\x7f\x00\x00\x000\x00\x00\x00\x07\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Forward=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x006\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00+\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00]\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xdc\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xbe\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\x7f`\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x02\xff\xa0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x07\xff\x90\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x05\xff\xd8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xec\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x17\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00?\xff\xf2\x00\x00\x00\x00\x7f\x00\x00\x00\x00?\xff\xfb\x00\x00\x00\x00\x7f\x00\x00\x00\x00_\xff\xfd\x80\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xfe\x80\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xfe@\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xff`\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xff\xb0\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\xd0\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\xc8\x00\x00\x00\x7f\x00\x00\x00\x0f\xff\xff\xff\xec\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\xff\xff\xf4\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xf2\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xff\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Left=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00b\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xce\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x01>\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x06~\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\r\xfe\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x13\xfe\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00g\xfe\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\xdf\xff\xff\xff\xff\xff\xf0\x00\x7f\x00\x00\x01?\xffUUUUX\x00\x7f\x00\x00\x06\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xff\xe8\x00\x7f\x00\x00\x17\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x00\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x01\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x01\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x00\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x00\x1f\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x00\x03\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x00\x01\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x00\x00\xff\xff\xff\xff\xff\xff\xf0\x00\x7f\x00\x00\x00?\xfe\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x1f\xfe\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x0f\xfe\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x03\xfe\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x01\xfe\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00~\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00>\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
No_go=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xfc>\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xc3\x80\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xf8`\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\x18\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\xff\xff\xcc\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xf3\x00\x00\x00\x7f\x00\x00\x00\x7f\xff\xc1\xff\xfd\x80\x00\x00\x7f\x00\x00\x00\xff\xfc\x00\x1f\xfc\xc0\x00\x00\x7f\x00\x00\x01\xff\xf0\x00\x03\xff`\x00\x00\x7f\x00\x00\x03\xff\xc0\x00\x00\xf7\xb0\x00\x00\x7f\x00\x00\x07\xff\x00\x00\x00\x7f\xd0\x00\x00\x7f\x00\x00\x0f\xfe\x00\x00\x00_\xe8\x00\x00\x7f\x00\x00\x0f\xf8\x00\x00\x00\xff\xf4\x00\x00\x7f\x00\x00\x1f\xf0\x00\x00\x01\x7f\xf4\x00\x00\x7f\x00\x00?\xf0\x00\x00\x03\xff\xfa\x00\x00\x7f\x00\x00?\xe0\x00\x00\x05\xff\xfb\x00\x00\x7f\x00\x00\x7f\xc0\x00\x00\x0f\xfd\xfd\x00\x00\x7f\x00\x00\x7f\xc0\x00\x00\x17\xf8\xfd\x00\x00\x7f\x00\x00\x7f\x80\x00\x00?\xf0\xff\x80\x00\x7f\x00\x00\xff\x80\x00\x00_\xe0~\x80\x00\x7f\x00\x00\xff\x00\x00\x00\xff\xc0\x7f\x80\x00\x7f\x00\x00\xff\x00\x00\x01\x7f\x80?@\x00\x7f\x00\x00\xfe\x00\x00\x03\xff\x00?@\x00\x7f\x00\x01\xfe\x00\x00\x05\xfe\x00?@\x00\x7f\x00\x01\xfe\x00\x00\x0f\xfc\x00\x1f\xc0\x00\x7f\x00\x01\xfe\x00\x00\x17\xf8\x00\x1f\xc0\x00\x7f\x00\x01\xfc\x00\x00?\xf0\x00\x1f\xe0\x00\x7f\x00\x01\xfc\x00\x00_\xe0\x00\x1f\xa0\x00\x7f\x00\x01\xfc\x00\x00\xff\xc0\x00\x1f\xe0\x00\x7f\x00\x01\xfc\x00\x01\x7f\x80\x00\x1f\xa0\x00\x7f\x00\x01\xfc\x00\x03\xff\x00\x00\x1f\xe0\x00\x7f\x00\x01\xfe\x00\x05\xfe\x00\x00\x1f\xe0\x00\x7f\x00\x01\xfe\x00\x0f\xfc\x00\x00\x1f\xc0\x00\x7f\x00\x01\xfe\x00\x17\xf8\x00\x00?\xc0\x00\x7f\x00\x01\xfe\x00?\xf0\x00\x00?\xc0\x00\x7f\x00\x00\xff\x00_\xe0\x00\x00?\xc0\x00\x7f\x00\x00\xff\x00\xff\xc0\x00\x00\x7f\xc0\x00\x7f\x00\x00\xff\x01\xff\x80\x00\x00\x7f\x80\x00\x7f\x00\x00\xff\x83\xff\x00\x00\x00\x7f\x80\x00\x7f\x00\x00\x7f\x87\xfe\x00\x00\x00\xff\x80\x00\x7f\x00\x00\x7f\xcf\xfc\x00\x00\x01\xff\x00\x00\x7f\x00\x00?\xff\xf8\x00\x00\x01\xff\x00\x00\x7f\x00\x00?\xff\xf0\x00\x00\x03\xfe\x00\x00\x7f\x00\x00\x1f\xff\xe0\x00\x00\x07\xfe\x00\x00\x7f\x00\x00\x1f\xff\xc0\x00\x00\x07\xfc\x00\x00\x7f\x00\x00\x0f\xff\x80\x00\x00\x1f\xfc\x00\x00\x7f\x00\x00\x07\xff\x00\x00\x00?\xf8\x00\x00\x7f\x00\x00\x07\xff\x80\x00\x00\xff\xf0\x00\x00\x7f\x00\x00\x03\xff\xe0\x00\x01\xff\xe0\x00\x00\x7f\x00\x00\x01\xff\xf8\x00\x0f\xff\xc0\x00\x00\x7f\x00\x00\x00\xff\xff\x00\x7f\xff\x80\x00\x00\x7f\x00\x00\x00\x7f\xff\xff\xff\xff\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\xff\xff\xfe\x00\x00\x00\x7f\x00\x00\x00\x0f\xff\xff\xff\xfc\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xff\xf0\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x00?\xff\xff\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x07\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00?\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Question_mark=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xf0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\x1e\x00\x00\x00\x00\x7f\x00\x00\x00\x00?\xff\xe3\x80\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xfc\xc0\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xff \x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xff\x90\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\xc8\x00\x00\x00\x7f\x00\x00\x00\x0f\xff\xff\xff\xe4\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\xf1\xff\xf2\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\x80\x7f\xf9\x00\x00\x00\x7f\x00\x00\x00?\xfe\x00\x1f\xfd\x00\x00\x00\x7f\x00\x00\x00?\xfc\x00\x07\xfd\x80\x00\x00\x7f\x00\x00\x00?\xf8\x00\x07\xfe\x80\x00\x00\x7f\x00\x00\x00\x7f\xf8\x00\x03\xfe\x80\x00\x00\x7f\x00\x00\x00\x7f\xf0\x00\x03\xfe\x80\x00\x00\x7f\x00\x00\x00\x7f\xf0\x00\x01\xfe\x80\x00\x00\x7f\x00\x00\x00\x7f\xf0\x00\x01\xff\x80\x00\x00\x7f\x00\x00\x00\x7f\xe0\x00\x01\xff\x80\x00\x00\x7f\x00\x00\x00\x7f\xe0\x00\x01\xff\x80\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x01\xff\x80\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x03\xff\x80\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x07\xff\x80\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x0f\xff\x80\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x1f\xff\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\xfe\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x7f\xfe\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\xff\xfc\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x01\xff\xf8\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x03\xff\xf0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x07\xff\xe0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0f\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1f\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00?\xff\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x7f\xfe\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x7f\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\xf8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\xf0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xfd\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xfe\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff@\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xa0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00>\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Right=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x000\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00&\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00;\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00,\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?`\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00/\xb0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\xcc\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00/\xf6\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\xfb\x00\x00\x00\x7f\x00\x07\xff\xff\xff\xff\xef\xfc\xc0\x00\x00\x7f\x00\x05UUUU_\xff`\x00\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xb0\x00\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xcc\x00\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xf6\x00\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xfb\x00\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xfc\xc0\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xff`\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xff\xb0\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xff\xb0\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xfe`\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xfc\x80\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xfb\x00\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xf6\x00\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xb0\x00\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff`\x00\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\x80\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\xff\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\xfc\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\xf8\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\xf0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Stop_1=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x01\xfc\x00\x00@\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xff \x00\x00\x00\x7f\x00\x00\x00\x07\x80\x00\x00\xd0\x00\x00\x00\x7f\x00\x00\x00\x0f\x00\x00\x00h\x00\x00\x00\x7f\x00\x00\x00\x1e\x7f\xff\xff4\x00\x00\x00\x7f\x00\x00\x00<\xff\xff\xff\x9a\x00\x00\x00\x7f\x00\x00\x00y\xff\xff\xff\xcd\x00\x00\x00\x7f\x00\x00\x00\xf3\xff\xff\xff\xe6\x80\x00\x00\x7f\x00\x00\x01\xe7\xff\xff\xff\xf3@\x00\x00\x7f\x00\x00\x03\xcf\xff\xff\xff\xf9\xa0\x00\x00\x7f\x00\x00\x07\x9f\xff\xff\xff\xfc\xd0\x00\x00\x7f\x00\x00\x0f?\xff\xff\xff\xfeh\x00\x00\x7f\x00\x00\x1e\x7f\xff\xff\xff\xff4\x00\x00\x7f\x00\x00<\xff\xff\xff\xff\xff\x9a\x00\x00\x7f\x00\x00y\xff\xff\xff\xff\xff\xcd\x00\x00\x7f\x00\x00\xf3\xff\xff\xff\xff\xff\xe6\x80\x00\x7f\x00\x01\xe7\xff\xff\xff\xff\xff\xf3@\x00\x7f\x00\x03\xcf\xff\xff\xff\xff\xff\xf9\xa0\x00\x7f\x00\x03\x9f\xff\xff\xff\xff\xff\xfc\xa0\x00\x7f\x00\x03\x9f\xff\xff\xff\xff\xff\xfc\xa0\x00\x7f\x00\x03\x9e\x0f\x00<\x0f\xc0<\xa0\x00\x7f\x00\x03\x9c\x02\x00\x18\x07\x80\x0c\xa0\x00\x7f\x00\x03\x98\x02\x00\x10\x03\x80\x04\xa0\x00\x7f\x00\x03\x90\xe1\xe0\xf1\xe3\x8f\xc4\xa0\x00\x7f\x00\x03\x91\xf7\xf1\xe3\xf1\x8f\xe4\xa0\x00\x7f\x00\x03\x91\xff\xf1\xe3\xf1\x8f\xe0\xa0\x00\x7f\x00\x03\x98\xff\xf1\xc7\xf9\x8f\xe4\xa0\x00\x7f\x00\x03\x98?\xf1\xc7\xf8\x8f\xc4\xa0\x00\x7f\x00\x03\x9c\x0f\xf1\xc7\xf8\x87\x84\xa0\x00\x7f\x00\x03\x9e\x03\xf1\xc7\xf8\x80\x0c\xa0\x00\x7f\x00\x03\x9f\x81\xf1\xc7\xf8\x80\x1c\xa0\x00\x7f\x00\x03\x9f\xe1\xf1\xc7\xf8\x87\xfc\xa0\x00\x7f\x00\x03\x9f\xf1\xf1\xc7\xf8\x87\xfc\xa0\x00\x7f\x00\x03\x9f\xf8\xf1\xe3\xf1\x87\xfc\xa0\x00\x7f\x00\x03\x9f\xf8\xf1\xe3\xf1\x87\xfc\xa0\x00\x7f\x00\x03\x91\xf1\xf1\xe1\xe1\x87\xfc\xa0\x00\x7f\x00\x03\x90\x01\xf1\xf0\xc3\x87\xfc\xa0\x00\x7f\x00\x03\x98\x01\xf1\xf8\x07\x87\xfc\xa0\x00\x7f\x00\x03\x9c\x07\xf1\xfc\x0f\x87\xfc\xa0\x00\x7f\x00\x03\x9f\x1f\xff\xff?\xff\xfc\xa0\x00\x7f\x00\x03\x9f\xff\xff\xff\xff\xff\xfc\xa0\x00\x7f\x00\x03\xcf\xff\xff\xff\xff\xff\xf9\xa0\x00\x7f\x00\x01\xe7\xff\xff\xff\xff\xff\xf3@\x00\x7f\x00\x00\xf3\xff\xff\xff\xff\xff\xe6\x80\x00\x7f\x00\x00y\xff\xff\xff\xff\xff\xcd\x00\x00\x7f\x00\x00<\xff\xff\xff\xff\xff\x9a\x00\x00\x7f\x00\x00\x1e\x7f\xff\xff\xff\xff4\x00\x00\x7f\x00\x00\x0f?\xff\xff\xff\xfeh\x00\x00\x7f\x00\x00\x07\x9f\xff\xff\xff\xfc\xf0\x00\x00\x7f\x00\x00\x03\xcf\xff\xff\xff\xf9\xe0\x00\x00\x7f\x00\x00\x01\xe7\xff\xff\xff\xf3\xc0\x00\x00\x7f\x00\x00\x00\xf3\xff\xff\xff\xe7\x80\x00\x00\x7f\x00\x00\x00y\xff\xff\xff\xcf\x00\x00\x00\x7f\x00\x00\x00<\xff\xff\xff\x9e\x00\x00\x00\x7f\x00\x00\x00\x1e\x7f\xff\xff<\x00\x00\x00\x7f\x00\x00\x00\x0f\x00\x00\x00x\x00\x00\x00\x7f\x00\x00\x00\x07\x80\x00\x00\xf0\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xff\xe0\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Stop_2=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x01\xfc\x00\x00@\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xff \x00\x00\x00\x7f\x00\x00\x00\x07\xc0\x00\x00\xd0\x00\x00\x00\x7f\x00\x00\x00\x0f\x00\x00\x00h\x00\x00\x00\x7f\x00\x00\x00\x1e\x00\x00\x004\x00\x00\x00\x7f\x00\x00\x00<\x00\x00\x00\x1a\x00\x00\x00\x7f\x00\x00\x00x\x00\x00\x00\r\x00\x00\x00\x7f\x00\x00\x00\xf0\x00\x00\x00\x06\x80\x00\x00\x7f\x00\x00\x01\xe0\x00\x00\x00\x03@\x00\x00\x7f\x00\x00\x03\xc0\x00\x00\x00\x01\xa0\x00\x00\x7f\x00\x00\x07\x80\x00\x00\x00\x00\xd0\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\x00\x00h\x00\x00\x7f\x00\x00\x1e\x00\x00\x00\x00\x004\x00\x00\x7f\x00\x00<\x00\x00\x00\x00\x00\x1a\x00\x00\x7f\x00\x00x\x00\x00\x00\x00\x00\r\x00\x00\x7f\x00\x00\xf0\x00\x00\x00\x00\x00\x06\x80\x00\x7f\x00\x01\xe0\x00\x00\x00\x00\x00\x03@\x00\x7f\x00\x03\xc0\x00\x00\x00\x00\x00\x01\xa0\x00\x7f\x00\x03\x80\x00\x00\x00\x00\x00\x00\xa0\x00\x7f\x00\x03\x80\x00\x00\x00\x00\x00\x00\xa0\x00\x7f\x00\x03\x81\xf0\xff\xc3\xf0?\xc0\xa0\x00\x7f\x00\x03\x83\xfd\xff\xe7\xf8\x7f\xf0\xa0\x00\x7f\x00\x03\x87\xff\xff\xef\xfc\x7f\xf8\xa0\x00\x7f\x00\x03\x8f\x1e\x1f\x0e\x1cp8\xa0\x00\x7f\x00\x03\x8e\x08\x0e\x1c\x0ep\x1c\xa0\x00\x7f\x00\x03\x8e\x00\x0e\x1c\x0ep\x1c\xa0\x00\x7f\x00\x03\x87\x00\x0e8\x06p\x1c\xa0\x00\x7f\x00\x03\x87\xc0\x0e8\x07p8\xa0\x00\x7f\x00\x03\x83\xf0\x0e8\x07xx\xa0\x00\x7f\x00\x03\x81\xfc\x0e8\x07\x7f\xf0\xa0\x00\x7f\x00\x03\x80~\x0e8\x07\x7f\xe0\xa0\x00\x7f\x00\x03\x80\x1e\x0e8\x07x\x00\xa0\x00\x7f\x00\x03\x80\x0e\x0e8\x07x\x00\xa0\x00\x7f\x00\x03\x80\x07\x0e\x1c\x0ex\x00\xa0\x00\x7f\x00\x03\x80\x07\x0e\x1c\x0ex\x00\xa0\x00\x7f\x00\x03\x8e\x0e\x0e\x1e\x1ex\x00\xa0\x00\x7f\x00\x03\x8f\xfe\x0e\x0f<x\x00\xa0\x00\x7f\x00\x03\x87\xfe\x0e\x07\xf8x\x00\xa0\x00\x7f\x00\x03\x83\xf8\x0e\x03\xf0x\x00\xa0\x00\x7f\x00\x03\x80\xe0\x00\x00\xc0\x00\x00\xa0\x00\x7f\x00\x03\x80\x00\x00\x00\x00\x00\x00\xa0\x00\x7f\x00\x03\xc0\x00\x00\x00\x00\x00\x01\xa0\x00\x7f\x00\x01\xe0\x00\x00\x00\x00\x00\x03@\x00\x7f\x00\x00\xf0\x00\x00\x00\x00\x00\x06\x80\x00\x7f\x00\x00x\x00\x00\x00\x00\x00\r\x00\x00\x7f\x00\x00<\x00\x00\x00\x00\x00\x1a\x00\x00\x7f\x00\x00\x1e\x00\x00\x00\x00\x004\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\x00\x00h\x00\x00\x7f\x00\x00\x07\x80\x00\x00\x00\x00\xf0\x00\x00\x7f\x00\x00\x03\xc0\x00\x00\x00\x01\xe0\x00\x00\x7f\x00\x00\x01\xe0\x00\x00\x00\x03\xc0\x00\x00\x7f\x00\x00\x00\xf0\x00\x00\x00\x07\x80\x00\x00\x7f\x00\x00\x00x\x00\x00\x00\x0f\x00\x00\x00\x7f\x00\x00\x00<\x00\x00\x00\x1e\x00\x00\x00\x7f\x00\x00\x00\x1e\x00\x00\x00<\x00\x00\x00\x7f\x00\x00\x00\x0f\x00\x00\x00x\x00\x00\x00\x7f\x00\x00\x00\x07\x80\x00\x00\xf0\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xff\xe0\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Thumbs_down=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x07\xff\xc0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x0f\xff\xc0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x0c\x00\xc7\xff\xff\xff\x00\x00\x00\x7f\x00\x00\x0e\xaa\xff\xff\xff\xff\xc0\x00\x00\x7f\x00\x00\rT\xff\xff\xff\xff\xc0\x00\x00\x7f\x00\x00\x0c\xaa\xff\xff\xff\xff\xc0\x00\x00\x7f\x00\x00\r\xfe\xff\xff\xff\xff\xc0\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xe0\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xea\xa0\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xd5@\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\r\xff\xc1\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\x0e\xaa\xc0\x7f\xff\xff\xe0\x00\x00\x7f\x00\x00\x0f\xff\xc0?\xff\xff\xe0\x00\x00\x7f\x00\x00\x07\xff\x80?\xff\xff\x80\x00\x00\x7f\x00\x00\x00\x00\x00\x1f\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0f\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x07\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x03\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x01\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x01\xfe\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x1f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x1f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x1f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x1f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x0f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x0f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Thumbs_up=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x0f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x0f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x1f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x1f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x1f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x1f\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x01\xfe\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x01\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x03\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x07\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0f\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1f\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x00?\xff\xff\x80\x00\x00\x7f\x00\x00\x07\xff\xc0?\xff\xff\xe0\x00\x00\x7f\x00\x00\x0f\xff\xc0\x7f\xff\xff\xe0\x00\x00\x7f\x00\x00\x0c\x00\xc1\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\rT\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\x0c\xaa\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\rT\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\r\xfe\xff\xff\xff\xea\xa0\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xea\xa0\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xf8\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xf0\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xe0\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xc0\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xc0\x00\x00\x7f\x00\x00\r\xff\xff\xff\xff\xff\xc0\x00\x00\x7f\x00\x00\x0f\xff\xff\xff\xff\xff\xc0\x00\x00\x7f\x00\x00\r\xff\xc7\xff\xff\xff\x00\x00\x00\x7f\x00\x00\rT\xc0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x0f\xff\xc0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x07\xff\x80\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Warning=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00?\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x7f\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff@\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xf3\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xf3\xa0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xe1\xf0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xe1\xd0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xc0\xf0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x07\xc0\xe8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\x80|\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\x80|\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\x00:\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\x00>\x00\x00\x00\x00\x7f\x00\x00\x00\x00>>\x1d\x00\x00\x00\x00\x7f\x00\x00\x00\x00<{\x0f\x00\x00\x00\x00\x7f\x00\x00\x00\x00|y\x0e\x80\x00\x00\x00\x7f\x00\x00\x00\x00\xf8\xfe\x87\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\xf8\xfe\x87\xc0\x00\x00\x00\x7f\x00\x00\x00\x01\xf0\xff\x83\xa0\x00\x00\x00\x7f\x00\x00\x00\x01\xf0\xfe\x83\xe0\x00\x00\x00\x7f\x00\x00\x00\x03\xe0\xff\x81\xd0\x00\x00\x00\x7f\x00\x00\x00\x03\xc0\xff\x80\xf0\x00\x00\x00\x7f\x00\x00\x00\x07\xc0\x7f\x00\xe8\x00\x00\x00\x7f\x00\x00\x00\x0f\x80\x7f\x00|\x00\x00\x00\x7f\x00\x00\x00\x0f\x80\x7f\x00t\x00\x00\x00\x7f\x00\x00\x00\x1f\x00\x7f\x00>\x00\x00\x00\x7f\x00\x00\x00\x1f\x00\x7f\x00>\x00\x00\x00\x7f\x00\x00\x00>\x00\x7f\x00\x1d\x00\x00\x00\x7f\x00\x00\x00>\x00\x7f\x00\x1f\x00\x00\x00\x7f\x00\x00\x00|\x00\x7f\x00\x0e\x80\x00\x00\x7f\x00\x00\x00\xf8\x00\x7f\x00\x07\xc0\x00\x00\x7f\x00\x00\x00\xf8\x00\x7f\x00\x07@\x00\x00\x7f\x00\x00\x01\xf0\x00\x7f\x00\x03\xe0\x00\x00\x7f\x00\x00\x01\xf0\x00\x7f\x00\x03\xe0\x00\x00\x7f\x00\x00\x03\xe0\x00>\x00\x01\xd0\x00\x00\x7f\x00\x00\x03\xe0\x00>\x00\x01\xf0\x00\x00\x7f\x00\x00\x07\xc0\x00>\x00\x00\xe8\x00\x00\x7f\x00\x00\x0f\xc0\x00>\x00\x00\xfc\x00\x00\x7f\x00\x00\x0f\x80\x00\x1c\x00\x00t\x00\x00\x7f\x00\x00\x1f\x00\x00\x00\x00\x00>\x00\x00\x7f\x00\x00\x1f\x00\x00\x00\x00\x00:\x00\x00\x7f\x00\x00>\x00\x00\x00\x00\x00\x1f\x00\x00\x7f\x00\x00>\x00\x00>\x00\x00\x1f\x00\x00\x7f\x00\x00|\x00\x00}\x00\x00\x0e\x80\x00\x7f\x00\x00\xfc\x00\x00~\x80\x00\x0f\xc0\x00\x7f\x00\x00\xf8\x00\x00\x7f\x80\x00\x07@\x00\x7f\x00\x01\xf8\x00\x00\x7f\x80\x00\x07\xe0\x00\x7f\x00\x01\xf0\x00\x00\x7f\x00\x00\x03\xa0\x00\x7f\x00\x03\xe0\x00\x00?\x00\x00\x01\xf0\x00\x7f\x00\x03\xe0\x00\x00\x1e\x00\x00\x01\xf0\x00\x7f\x00\x07\xc0\x00\x00\x00\x00\x00\x00\xe8\x00\x7f\x00\x0f\xc0\x00\x00\x00\x00\x00\x00\xfc\x00\x7f\x00\x0f\x80\x00\x00\x00\x00\x00\x00\xf4\x00\x7f\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xfe\x00\x7f\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xfe\x00\x7f\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xfe\x00\x7f\x00\x07\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
YES=Accept
|
||||
NO=Decline
|
||||
259
mixly/boards/default/micropython/build/lib/irremote.py
Normal file
259
mixly/boards/default/micropython/build/lib/irremote.py
Normal file
@@ -0,0 +1,259 @@
|
||||
"""
|
||||
IR-Remote
|
||||
|
||||
Micropython library for the IR-Remote/Timer(IR_RX&TX)
|
||||
===============================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import array, time, gc
|
||||
from machine import Pin, Timer
|
||||
from os import uname
|
||||
try:
|
||||
from esp32 import RMT
|
||||
TX_MOED = 1
|
||||
except:
|
||||
from machine import PWM
|
||||
TX_MOED = 0
|
||||
|
||||
'''接收部分'''
|
||||
class IR_RX:
|
||||
BADSTART = 'Invalid start pulse'
|
||||
BADDATA = 'Invalid data'
|
||||
def __init__(self, pin, callback=None, timeout=15000, timer_id=1):
|
||||
self._start = 0
|
||||
self._ready = False
|
||||
self._enable = False
|
||||
self._timeout = timeout
|
||||
self._callback = callback
|
||||
self._pulses = array.array('H')
|
||||
self.code = [None, None, None, memoryview(self._pulses)] #存放[cmd, addr, data, pulses]
|
||||
Pin(pin, Pin.IN).irq(handler=self._irq_cb, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING))
|
||||
Timer(0 if "-C2" in uname().machine else timer_id).init(period=5, mode=Timer.PERIODIC, callback=self._timer_cb)
|
||||
|
||||
def _irq_cb(self, pin):
|
||||
if not self._enable:
|
||||
_intime = time.ticks_us()
|
||||
if self._start == 0:
|
||||
self._start = _intime
|
||||
return
|
||||
self._pulses.append(time.ticks_diff(_intime, self._start))
|
||||
self._start = _intime
|
||||
else:
|
||||
self._start = 0
|
||||
self._pulses = array.array('H')
|
||||
|
||||
def _timer_cb(self, tim):
|
||||
if len(self._pulses) >= 3 and time.ticks_diff(time.ticks_us(), self._start) > self._timeout:
|
||||
#接收完成,开始解码
|
||||
self.code[3] = memoryview(self._pulses)
|
||||
if self.decode() is None and self._callback:
|
||||
self._callback(self.code[0], self.code[1], self.code[2], self.code[3])
|
||||
self._ready = True
|
||||
self._start = 0
|
||||
self._pulses = array.array('H')
|
||||
gc.collect()
|
||||
|
||||
def recv_cb(self, callback):
|
||||
self._callback = callback
|
||||
|
||||
def timeout(self, timeout=15000):
|
||||
self._timeout = timeout
|
||||
|
||||
def any(self):
|
||||
ready = self._ready
|
||||
self._ready = False
|
||||
return ready
|
||||
|
||||
def enable(self, onoff):
|
||||
self._enable = onoff
|
||||
|
||||
class NEC_RX(IR_RX):
|
||||
def __init__(self, pin, bits=None, callback=None, timer_id=1):
|
||||
super().__init__(pin, callback, timer_id=timer_id)
|
||||
self._bits = bits
|
||||
|
||||
def decode(self):
|
||||
pulse_len = len(self._pulses)
|
||||
if pulse_len < 3:
|
||||
print("Warning:", self.BADSTART)
|
||||
return False
|
||||
else:
|
||||
start_i = 0
|
||||
value = 0
|
||||
#跳过帧头(各厂家定义不一)
|
||||
for i in range(pulse_len):
|
||||
if self._pulses[i] <= 2250:
|
||||
start_i = i
|
||||
break
|
||||
val = 1 << ((pulse_len - start_i - 1) // 2) - 1 if (pulse_len - start_i) >= 3 else 0
|
||||
#根据高低脉冲定义转码
|
||||
for edge in range(start_i, pulse_len - 1, 2):
|
||||
value >>= 1
|
||||
if self._pulses[edge + 1] > 1120:
|
||||
value |= val
|
||||
#判读是8、16位解码
|
||||
if self._bits == 8 or self._bits == 16:
|
||||
cmd = value >> 16 & 0xff
|
||||
if cmd != (value >> 24 ^ 0xff) and value != 0x0:
|
||||
print("Warning:", self.BADDATA)
|
||||
return False
|
||||
addr = value & 0xff if self._bits == 8 else value & 0xffff
|
||||
self.code[0:3] = cmd, addr, value
|
||||
#其他未定义直接输出转码
|
||||
else:
|
||||
self.code[0:3] = None, None, value
|
||||
|
||||
class RC5_RX(IR_RX):
|
||||
def __init__(self, pin, callback=None, timer_id=1):
|
||||
super().__init__(pin, callback, timer_id=timer_id)
|
||||
|
||||
def decode(self):
|
||||
pulse_len = len(self._pulses)
|
||||
if pulse_len < 3:
|
||||
print("Warning:", self.BADSTART)
|
||||
return False
|
||||
else:
|
||||
bit = 1
|
||||
value = 0
|
||||
num = 0
|
||||
while True:
|
||||
short = self._pulses[num] < 1334
|
||||
if not short:
|
||||
bit ^= 1
|
||||
value <<= 1
|
||||
value |= bit
|
||||
num += 1 + int(short)
|
||||
if num >= pulse_len:
|
||||
value >>= 1
|
||||
break
|
||||
#判读解码
|
||||
cmd = (value & 0x3f) | (0 if ((value >> 12) & 1) else 0x40)
|
||||
addr = (value >> 6) & 0x1f
|
||||
self.code[0:3] = cmd, addr, value
|
||||
|
||||
'''发射部分'''
|
||||
class IR_TX:
|
||||
def __init__(self, pin, cfreq=38000, power=60):
|
||||
if TX_MOED:
|
||||
self._rmt = RMT(0, pin=Pin(pin), clock_div=80, tx_carrier = (cfreq, round(power * 0.75), 1))
|
||||
else:
|
||||
self._pwm = PWM(Pin(pin), freq=cfreq, duty_u16=0)
|
||||
self._duty = round(power * 65535 / 100 * 0.75)
|
||||
self._busy = False
|
||||
self._pulses = array.array('H')
|
||||
self.carrier = False
|
||||
|
||||
def _pwm_write_pulses(self, pulses):
|
||||
_flip = True
|
||||
self._busy = True
|
||||
for pulse in pulses:
|
||||
if _flip:
|
||||
self._pwm.duty_u16(self._duty)
|
||||
time.sleep_us(pulse)
|
||||
_flip = False
|
||||
else:
|
||||
self._pwm.duty_u16(0)
|
||||
time.sleep_us(pulse)
|
||||
_flip = True
|
||||
self._pwm.duty_u16(0)
|
||||
self._busy = False
|
||||
|
||||
def transmit(self, cmd=None, addr=None, toggle=None, pulses=None, raw=None):
|
||||
if pulses is None:
|
||||
self.carrier = False
|
||||
if raw is None:
|
||||
self.tx(cmd, addr, toggle)
|
||||
else:
|
||||
self.tx_raw(raw)
|
||||
if TX_MOED:
|
||||
self._rmt.write_pulses(tuple(self._pulses))
|
||||
else:
|
||||
self._pwm_write_pulses(tuple(self._pulses))
|
||||
self._pulses = array.array('H')
|
||||
else:
|
||||
if TX_MOED:
|
||||
self._rmt.write_pulses(tuple(pulses))
|
||||
else:
|
||||
self._pwm_write_pulses(tuple(pulses))
|
||||
|
||||
def busy(self):
|
||||
return not self._rmt.wait_done() if TX_MOED else self._busy
|
||||
|
||||
def _append(self, *times):
|
||||
for t in times:
|
||||
self._pulses.append(t)
|
||||
self.carrier = not self.carrier
|
||||
|
||||
def _add(self, t):
|
||||
assert t > 0
|
||||
self._pulses[len(self._pulses)-1] +=t
|
||||
|
||||
class NEC_TX(IR_TX):
|
||||
_TBURST = const(563)
|
||||
_T_ONE = const(1687)
|
||||
def __init__(self, pin, samsung=False, power=60):
|
||||
super().__init__(pin, 38000, power)
|
||||
self._samsung = samsung
|
||||
|
||||
def _bit(self, b):
|
||||
self._append(_TBURST, _T_ONE if b else _TBURST)
|
||||
|
||||
def tx(self, cmd, addr, toggle=0): #cmd:0~0xff, addr:0~0xffff, toggle:0,1
|
||||
if self._samsung:
|
||||
self._append(4500, 4500)
|
||||
else:
|
||||
self._append(9000, 4500)
|
||||
if addr < 256: # Short address: append complement
|
||||
if self._samsung:
|
||||
addr |= addr << 8
|
||||
else:
|
||||
addr |= ((addr ^ 0xff) << 8)
|
||||
for _ in range(16):
|
||||
self._bit(addr & 1)
|
||||
addr >>= 1
|
||||
cmd |= ((cmd ^ 0xff) << 8)
|
||||
for _ in range(16):
|
||||
self._bit(cmd & 1)
|
||||
cmd >>= 1
|
||||
self._append(_TBURST)
|
||||
if toggle == 1:
|
||||
self._append(30000, 9000, 2250, _TBURST)
|
||||
|
||||
def tx_raw(self, raw):
|
||||
self._append(9000, 4500)
|
||||
while raw:
|
||||
self._bit(raw & 1)
|
||||
raw >>= 1
|
||||
self._append(_TBURST)
|
||||
|
||||
class RC5_TX(IR_TX):
|
||||
_T_RC5 = const(889)
|
||||
def __init__(self, pin, power=60):
|
||||
super().__init__(pin, 36000, power)
|
||||
|
||||
def tx(self, cmd, addr, toggle): #cmd:0~0x3f, addr:0~0x1f, toggle:0,1
|
||||
d = (cmd & 0x3f) | ((addr & 0x1f) << 6) | (((cmd & 0x40) ^ 0x40) << 6) | ((toggle & 1) << 11)
|
||||
mask = 0x2000
|
||||
while mask:
|
||||
if mask == 0x2000:
|
||||
self._append(_T_RC5)
|
||||
else:
|
||||
bit = bool(d & mask)
|
||||
if bit ^ self.carrier:
|
||||
self._add(_T_RC5)
|
||||
self._append(_T_RC5)
|
||||
else:
|
||||
self._append(_T_RC5, _T_RC5)
|
||||
mask >>= 1
|
||||
|
||||
def tx_raw(self, raw):
|
||||
self._append(_T_RC5)
|
||||
mask = 1 << len(bin(raw)) - 3
|
||||
while mask:
|
||||
if bool(raw & mask) ^ self.carrier:
|
||||
self._add(_T_RC5)
|
||||
self._append(_T_RC5)
|
||||
else:
|
||||
self._append(_T_RC5, _T_RC5)
|
||||
mask >>= 1
|
||||
self._append(_T_RC5)
|
||||
49
mixly/boards/default/micropython/build/lib/keypad.py
Normal file
49
mixly/boards/default/micropython/build/lib/keypad.py
Normal file
@@ -0,0 +1,49 @@
|
||||
"""
|
||||
Simple Keypad
|
||||
|
||||
Micropython library for the Simple Keypad
|
||||
=======================================================
|
||||
|
||||
#Based on Author: 'Teeraphat Kullanankanjana'
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
from machine import Pin
|
||||
from time import sleep
|
||||
|
||||
class Keypad:
|
||||
def __init__(self, row_pins, column_pins, keys):
|
||||
"""Initialize the keypad object."""
|
||||
if not all(isinstance(pin, Pin) for pin in row_pins):
|
||||
raise ValueError("Row pins must be instances of Pin.")
|
||||
|
||||
if not all(isinstance(pin, Pin) for pin in column_pins):
|
||||
raise ValueError("Column pins must be instances of Pin.")
|
||||
|
||||
if not isinstance(keys, list) or not all(isinstance(row, list) for row in keys):
|
||||
raise ValueError("Keys must be a 2D list.")
|
||||
|
||||
self.row_pins = row_pins
|
||||
self.column_pins = column_pins
|
||||
self.keys = keys
|
||||
|
||||
for pin in self.row_pins:
|
||||
pin.init(Pin.IN, Pin.PULL_UP)
|
||||
|
||||
for pin in self.column_pins:
|
||||
pin.init(Pin.OUT)
|
||||
|
||||
if len(self.row_pins) > len(self.keys) or len(self.column_pins) > len(self.keys[0]):
|
||||
raise ValueError("Number of row/column pins does not match the key layout size.")
|
||||
|
||||
def read_keypad(self):
|
||||
"""Read the keypad and return the pressed key."""
|
||||
for col_pin in self.column_pins:
|
||||
col_pin.value(0)
|
||||
for i, row_pin in enumerate(self.row_pins):
|
||||
if not row_pin.value():
|
||||
key_pressed = self.keys[i][self.column_pins.index(col_pin)]
|
||||
col_pin.value(1)
|
||||
return key_pressed
|
||||
col_pin.value(1)
|
||||
return None
|
||||
76
mixly/boards/default/micropython/build/lib/ltr308al.py
Normal file
76
mixly/boards/default/micropython/build/lib/ltr308al.py
Normal file
@@ -0,0 +1,76 @@
|
||||
"""
|
||||
LTR-308ALS
|
||||
|
||||
Micropython library for the LTR-308ALS
|
||||
=======================================================
|
||||
|
||||
#Changed from circuitpython to micropython 20220211
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
LTR_308ALS_ADDRESS = const(0x53)
|
||||
|
||||
LTR_308ALS_REG_CTRL = const(0x00)
|
||||
LTR_308ALS_REG_GAIN = const(0x05) #设置增益
|
||||
LTR_308ALS_REG_DEVICE_ID = const(0x06)
|
||||
LTR_308ALS_REG_DATA = const(0x0D)
|
||||
|
||||
#设置增益范围
|
||||
LTR_308ALS_CMD_ALS_Enable = const(0x02)
|
||||
LTR_308ALS_CMD_X1GAIN =const(0x00)
|
||||
LTR_308ALS_CMD_X3GAIN =const(0x01)
|
||||
LTR_308ALS_CMD_X6GAIN =const(0x02)
|
||||
LTR_308ALS_CMD_X9GAIN =const(0x03)
|
||||
LTR_308ALS_CMD_X18GAIN =const(0x04)
|
||||
|
||||
_GAINS = (
|
||||
LTR_308ALS_CMD_X1GAIN, # 1x
|
||||
LTR_308ALS_CMD_X3GAIN, # 3x
|
||||
LTR_308ALS_CMD_X6GAIN, # 6x
|
||||
LTR_308ALS_CMD_X9GAIN, # 9x
|
||||
LTR_308ALS_CMD_X18GAIN # 18x
|
||||
)
|
||||
|
||||
_GAINS_X = (
|
||||
1, # 1x
|
||||
3, # 3x
|
||||
6, # 6x
|
||||
9, # 9x
|
||||
18 # 18x
|
||||
)
|
||||
|
||||
class LTR_308ALS:
|
||||
def __init__(self, i2c_bus,gain=1):
|
||||
self._device = i2c_bus
|
||||
self._address = LTR_308ALS_ADDRESS
|
||||
self._gain = gain
|
||||
|
||||
if self._chip_id() != 0xB1:
|
||||
raise AttributeError("Cannot find a LTR_308ALS")
|
||||
self._Enable() #star
|
||||
time.sleep(0.2)
|
||||
self._wreg(LTR_308ALS_REG_GAIN,_GAINS[self._gain])
|
||||
|
||||
#Write memory address
|
||||
def _wreg(self, reg, val):
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
#Read memory address
|
||||
def _rreg(self, reg,nbytes=1):
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _chip_id(self):
|
||||
return self._rreg(LTR_308ALS_REG_DEVICE_ID)
|
||||
|
||||
def _Enable(self):
|
||||
self._wreg(LTR_308ALS_REG_CTRL,LTR_308ALS_CMD_ALS_Enable)
|
||||
|
||||
def getdata(self):
|
||||
buffer=self._rreg(LTR_308ALS_REG_DATA,3)
|
||||
als_data= buffer[2]<<16 | buffer[1]<<8| buffer[0]
|
||||
als_lux=float(0.6*als_data/_GAINS_X[self._gain])
|
||||
return als_lux
|
||||
|
||||
78
mixly/boards/default/micropython/build/lib/ltr381rgb.py
Normal file
78
mixly/boards/default/micropython/build/lib/ltr381rgb.py
Normal file
@@ -0,0 +1,78 @@
|
||||
"""
|
||||
LTR-381RGB-XX
|
||||
|
||||
MicroPython library for the LTR-381RGB-XX (Color sensor)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20230417
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
LTR_MAIN_CTRL = const(0x00)
|
||||
LTR_ALS_CS_MEAS_RATE = const(0x04)
|
||||
LTR_ALS_CS_GAIN = const(0x05)
|
||||
LTR_PART_ID = const(0x06)
|
||||
LTR_MAIN_STATUS = const(0x07)
|
||||
LTR_CS_DATA = const(0x0A)
|
||||
#1x 3x 6x 9x 18x
|
||||
_GAINS_X = (1, 3, 6, 9, 18)
|
||||
|
||||
class LTR_381RGB:
|
||||
def __init__(self, i2c_bus, addr=0x53, gain=1):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
self._gain = gain
|
||||
self._color = [0, 0, 0]
|
||||
self._ir = 0
|
||||
self._als = 0
|
||||
|
||||
if (self._chip_id() & 0xF0) != 0xC0:
|
||||
raise AttributeError("Cannot find a LTR-381RGB")
|
||||
|
||||
self._configure()
|
||||
time.sleep(0.1)
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _chip_id(self):
|
||||
'''Proofreading device ID'''
|
||||
return self._rreg(LTR_PART_ID)
|
||||
|
||||
def _configure(self):
|
||||
'''Configuration Register'''
|
||||
self._wreg(LTR_MAIN_CTRL, 0x06) #CS mode & ALS/CS Enable
|
||||
self._wreg(LTR_ALS_CS_MEAS_RATE, 0x22) #Resolution = 18 bit, Meas Rate =100ms
|
||||
self._wreg(LTR_ALS_CS_GAIN, self._gain & 0x07) #CS measurement Gain Range
|
||||
|
||||
def status(self):
|
||||
'''Data conversion status'''
|
||||
return self._rreg(LTR_MAIN_STATUS) & 0x08
|
||||
|
||||
def getdata(self):
|
||||
'''Processing data acquisition'''
|
||||
if self.status():
|
||||
_buf=self._rreg(LTR_CS_DATA, 12)
|
||||
self._ir = _buf[2] << 16 | _buf[1] << 8 | _buf[0]
|
||||
self._color [1] = _buf[5] << 16 | _buf[4] << 8 | _buf[3]
|
||||
self._color [0] = _buf[8] << 16 | _buf[7] << 8 | _buf[6]
|
||||
self._color [2] = _buf[11] << 16 | _buf[10] << 8 | _buf[9]
|
||||
self._als = 0.8 * self._color [1] * (1 - 0.033 * self._ir / self._color [1]) / _GAINS_X[self._gain]
|
||||
return round(self._als, 2), self._ir, self._color
|
||||
|
||||
def color(self):
|
||||
return self.getdata()[2]
|
||||
|
||||
def ir(self):
|
||||
return self.getdata()[1]
|
||||
|
||||
def als(self):
|
||||
return self.getdata()[0]
|
||||
75
mixly/boards/default/micropython/build/lib/ltr390uv.py
Normal file
75
mixly/boards/default/micropython/build/lib/ltr390uv.py
Normal file
@@ -0,0 +1,75 @@
|
||||
"""
|
||||
LTR-390UV
|
||||
|
||||
Micropython library for the LTR-390UV(ALS+UV)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20240120
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
_LTR390_ADDRESS = const(0x53)
|
||||
_LTR390_REG_CTRL = const(0x00)
|
||||
_LTR390_REG_MEAS = const(0x04)
|
||||
_LTR390_REG_GAIN = const(0x05)
|
||||
_LTR390_REG_ID = const(0x06)
|
||||
_LTR390_REG_ALS = const(0x0D)
|
||||
_LTR390_REG_UVS = const(0x10)
|
||||
|
||||
_RATE_DEFAULT = const(0x02) #100ms
|
||||
_RESOLUTION_20BIT = (0<<4, 4)
|
||||
_RESOLUTION_19BIT = (1<<4, 2)
|
||||
_RESOLUTION_18BIT = (2<<4, 1)
|
||||
_RESOLUTION_17BIT = (3<<4, 0.5)
|
||||
_RESOLUTION_16BIT = (4<<4, 0.25)
|
||||
_RESOLUTION_13BIT = (5<<4, 0.125)
|
||||
|
||||
_GAIN_X1 = (0, 1)
|
||||
_GAIN_X3 = (1, 3)
|
||||
_GAIN_X6 = (2, 6)
|
||||
_GAIN_X9 = (3, 9)
|
||||
_GAIN_X18 = (4, 18)
|
||||
|
||||
class ALS_UVS:
|
||||
def __init__(self, i2c_bus, addr=_LTR390_ADDRESS, gain=_GAIN_X1, resolution=_RESOLUTION_17BIT):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
self._gain = gain
|
||||
self._reso = resolution
|
||||
self._flaga = False
|
||||
self._flagu = False
|
||||
|
||||
if self._rreg(_LTR390_REG_ID) != 0xB2:
|
||||
raise AttributeError("Cannot find a LTR-390UV")
|
||||
|
||||
self._wreg(_LTR390_REG_MEAS, self._reso[0] | _RATE_DEFAULT)
|
||||
self._wreg(_LTR390_REG_GAIN, self._gain[0])
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def ultraviolet(self):
|
||||
if not self._flagu:
|
||||
self._wreg(_LTR390_REG_CTRL, 0x0A) #UVS in Active Mode
|
||||
time.sleep_ms(int(self._reso[1] * 100))
|
||||
self._flagu = True
|
||||
self._flaga = False
|
||||
buf = self._rreg(_LTR390_REG_UVS, 3)
|
||||
return buf[2] << 16 | buf[1] << 8 | buf[0]
|
||||
|
||||
def ambient_light(self):
|
||||
if not self._flaga:
|
||||
self._wreg(_LTR390_REG_CTRL, 0x02) #ALS in Active Mode
|
||||
time.sleep_ms(int(self._reso[1] * 100))
|
||||
self._flaga = True
|
||||
self._flagu = False
|
||||
buf = self._rreg(_LTR390_REG_ALS, 3)
|
||||
return 0.6 * (buf[2] << 16 | buf[1] << 8 | buf[0]) / (self._gain[1] * self._reso[1])
|
||||
106
mixly/boards/default/micropython/build/lib/ltr553als.py
Normal file
106
mixly/boards/default/micropython/build/lib/ltr553als.py
Normal file
@@ -0,0 +1,106 @@
|
||||
"""
|
||||
LTR-553ALS-XX
|
||||
|
||||
MicroPython library for the LTR-553ALS-XX(ALS,PS)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20220224
|
||||
#Format unified 20220623
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
LTR_553ALS_ADDRESS = const(0x23)
|
||||
LTR_ALS_REG_CONTR = const(0x80)
|
||||
LTR_PS_REG_CONTR = const(0x81)
|
||||
LTR_PS_REG_LED = const(0x82)
|
||||
LTR_PS_REG_PULSES = const(0x83)
|
||||
LTR_PS_REG_RATE = const(0x84)
|
||||
LTR_ALS_REG_RATE = const(0x85)
|
||||
LTR_553ALS_REG_ID = const(0x87)
|
||||
LTR_ALS_REG_DATA1 = const(0x88)
|
||||
LTR_553ALS_REG_ATATUS = const(0x8C)
|
||||
LTR_PS_REG_DATA1 = const(0x8D)
|
||||
|
||||
_ALS_GAIN={
|
||||
"X1":(1,0x01), # For Gain X1
|
||||
"X2":(2,0x05), # For Gain X2
|
||||
"X4":(4,0x09), # For Gain X4
|
||||
"X8":(8,0x0D), # For Gain X8
|
||||
"X48":(48,0x19), # For Gain X48
|
||||
"X96":(96,0x1D), # For Gain X96
|
||||
}
|
||||
|
||||
class LTR_553ALS:
|
||||
|
||||
def __init__(self, i2c_bus,addr=LTR_553ALS_ADDRESS,ALS_Gain="X1"):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
self.ALS_IR = 0
|
||||
self.ALS_VIS = 0
|
||||
self.PS = 0
|
||||
self.ALS_gain = ALS_Gain
|
||||
|
||||
if self._chip_id() != 0x05:
|
||||
raise AttributeError("Cannot find a LTR_553ALS")
|
||||
|
||||
self._configure()
|
||||
#time.sleep(0.1)
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg,nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _chip_id(self):
|
||||
'''校对设备ID'''
|
||||
return self._rreg(LTR_553ALS_REG_ID)
|
||||
|
||||
def _configure(self):
|
||||
'''配置寄存器'''
|
||||
self._wreg(LTR_ALS_REG_CONTR,_ALS_GAIN[self.ALS_gain][1]) # ALS_CONTR: Active mode
|
||||
self._wreg(LTR_PS_REG_CONTR,0x03) # PS_CONTR: Active mode
|
||||
self._wreg(LTR_PS_REG_LED,0x5B) #PS_LED: LED_pulse_period=50khz,DUTY = 100%,LED_pulsed_current_level = 50mA
|
||||
self._wreg(LTR_PS_REG_PULSES,0x0A) #PS_N_Pulses: Number_of_pulses = 10
|
||||
self._wreg(LTR_PS_REG_RATE,0x08) #PS_Measurement_Rate=10ms
|
||||
self._wreg(LTR_ALS_REG_RATE,0x12) #ALS_Measurement_Rate=200ms,ALS_integration_time=200ms
|
||||
|
||||
def _status(self):
|
||||
'''数据转换状态'''
|
||||
status=self._rreg(LTR_553ALS_REG_ATATUS)
|
||||
return status&0x84, status&0x01 #ALS,PS status
|
||||
|
||||
@property
|
||||
def getdata(self):
|
||||
'''处理获取数据'''
|
||||
if self._status()[0]:
|
||||
data_als=self._rreg(LTR_ALS_REG_DATA1,4)
|
||||
als_ch1=data_als[0] | data_als[1]<<8
|
||||
als_ch0=data_als[2] | data_als[3]<<8
|
||||
ratio=als_ch1/(als_ch1+als_ch0) if (als_ch1+als_ch0)>0 else 0
|
||||
self.ALS_IR =als_ch1*ratio/_ALS_GAIN[self.ALS_gain][0]
|
||||
self.ALS_VIS=als_ch0*ratio/_ALS_GAIN[self.ALS_gain][0]
|
||||
|
||||
if self._status()[1]:
|
||||
data_ps=self._rreg(LTR_PS_REG_DATA1,2)
|
||||
self.PS =data_ps[0] | data_ps[1]<<8
|
||||
|
||||
return round(self.ALS_VIS,2),round(self.ALS_IR,2),self.PS
|
||||
|
||||
def als_vis(self):
|
||||
'''可见光Lux'''
|
||||
return self.getdata[0]
|
||||
|
||||
def als_ir(self):
|
||||
'''红外Lux'''
|
||||
return self.getdata[1]
|
||||
|
||||
def ps_nl(self):
|
||||
'''接近距离'''
|
||||
return self.getdata[2]
|
||||
1110
mixly/boards/default/micropython/build/lib/map.json
Normal file
1110
mixly/boards/default/micropython/build/lib/map.json
Normal file
File diff suppressed because it is too large
Load Diff
97
mixly/boards/default/micropython/build/lib/matcher.py
Normal file
97
mixly/boards/default/micropython/build/lib/matcher.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# SPDX-FileCopyrightText: 2017 Yoch <https://github.com/yoch>
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-1.0
|
||||
|
||||
"""
|
||||
`matcher`
|
||||
====================================================================================
|
||||
|
||||
MQTT topic filter matcher from the Eclipse Project's Paho.MQTT.Python
|
||||
https://github.com/eclipse/paho.mqtt.python/blob/master/src/paho/mqtt/matcher.py
|
||||
* Author(s): Yoch (https://github.com/yoch)
|
||||
"""
|
||||
|
||||
|
||||
class MQTTMatcher:
|
||||
"""Intended to manage topic filters including wildcards.
|
||||
|
||||
Internally, MQTTMatcher use a prefix tree (trie) to store
|
||||
values associated with filters, and has an iter_match()
|
||||
method to iterate efficiently over all filters that match
|
||||
some topic name.
|
||||
"""
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
class Node:
|
||||
"""Individual node on the MQTT prefix tree."""
|
||||
|
||||
__slots__ = "children", "content"
|
||||
|
||||
def __init__(self):
|
||||
self.children = {}
|
||||
self.content = None
|
||||
|
||||
def __init__(self):
|
||||
self._root = self.Node()
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
"""Add a topic filter :key to the prefix tree
|
||||
and associate it to :value"""
|
||||
node = self._root
|
||||
for sym in key.split("/"):
|
||||
node = node.children.setdefault(sym, self.Node())
|
||||
node.content = value
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""Retrieve the value associated with some topic filter :key"""
|
||||
try:
|
||||
node = self._root
|
||||
for sym in key.split("/"):
|
||||
node = node.children[sym]
|
||||
if node.content is None:
|
||||
raise KeyError(key)
|
||||
return node.content
|
||||
except KeyError:
|
||||
raise KeyError(key) from None
|
||||
|
||||
def __delitem__(self, key):
|
||||
"""Delete the value associated with some topic filter :key"""
|
||||
lst = []
|
||||
try:
|
||||
parent, node = None, self._root
|
||||
for k in key.split("/"):
|
||||
parent, node = node, node.children[k]
|
||||
lst.append((parent, k, node))
|
||||
node.content = None
|
||||
except KeyError:
|
||||
raise KeyError(key) from None
|
||||
else: # cleanup
|
||||
for parent, k, node in reversed(lst):
|
||||
if node.children or node.content is not None:
|
||||
break
|
||||
del parent.children[k]
|
||||
|
||||
def iter_match(self, topic):
|
||||
"""Return an iterator on all values associated with filters
|
||||
that match the :topic"""
|
||||
lst = topic.split("/")
|
||||
normal = not topic.startswith("$")
|
||||
|
||||
def rec(node, i=0):
|
||||
if i == len(lst):
|
||||
if node.content is not None:
|
||||
yield node.content
|
||||
else:
|
||||
part = lst[i]
|
||||
if part in node.children:
|
||||
for content in rec(node.children[part], i + 1):
|
||||
yield content
|
||||
if "+" in node.children and (normal or i > 0):
|
||||
for content in rec(node.children["+"], i + 1):
|
||||
yield content
|
||||
if "#" in node.children and (normal or i > 0):
|
||||
content = node.children["#"].content
|
||||
if content is not None:
|
||||
yield content
|
||||
|
||||
return rec(self._root)
|
||||
71
mixly/boards/default/micropython/build/lib/matrix16x8.py
Normal file
71
mixly/boards/default/micropython/build/lib/matrix16x8.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""
|
||||
Matrix16x8 Displays
|
||||
|
||||
Micropython library for the HT16K33 Matrix16x8 Displays
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20230411
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
from ht16k33 import HT16K33
|
||||
|
||||
class Matrix(HT16K33):
|
||||
"""A single matrix."""
|
||||
def __init__(self, i2c, address=0x70, brightness=0.3, font="5x8", font_address=0x3A0000, width=16, height=8):
|
||||
super().__init__(i2c, address, brightness, width, height)
|
||||
self.font(font)
|
||||
self.uin_font(font_address)
|
||||
|
||||
"""Graph module"""
|
||||
HEART=b' \x02p\x07\xf8\x0f\xf8\x0f\xf0\x07\xe0\x03\xc0\x01\x80\x00'
|
||||
HEART_SMALL=b'\x00\x00 \x02p\x07\xf0\x07\xe0\x03\xc0\x01\x80\x00\x00\x00'
|
||||
HAPPY=b'\x00\x00\x00\x00\x18\x18\x18\x18\x00\x00 \x04@\x02\x80\x01'
|
||||
SAD=b'\x00\x00\x00\x008\x1c\x04 \x00\x00\x80\x01@\x02 \x04'
|
||||
SMILE=b'\x00\x00\x18\x18$$\x00\x00\x00\x00 \x04@\x02\x80\x01'
|
||||
SILLY=b'\x00\x00\x18\x18$$\x18\x18\x00\x00\xc0\x03@\x02\x80\x01'
|
||||
FABULOUS=b'8\x1cD"|>\x00\x00\x00\x00\xe0\x07 \x04\xc0\x03'
|
||||
SURPRISED=b'\x00\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x00\x00\x80\x00'
|
||||
ASLEEP=b'\x00\x00\x00\x00<<\x00\x00\x00\x00\xc0\x03 \x04\xc0\x03'
|
||||
ANGRY=b'D"(\x14\x10\x08\x00\x00\x80\x01@\x02 \x04\x10\x08'
|
||||
CONFUSED=b'\x00\x00\xc0\x01 \x02\x00\x02\x00\x01\x80\x00\x00\x00\x80\x00'
|
||||
NO=b'\x00\x00\x10\x02 \x01\xc0\x00\xc0\x00 \x01\x10\x02\x00\x00'
|
||||
YES=b'\x00\x00\x00\x10\x00\x08\x00\x04\x10\x02 \x01\xc0\x00\x00\x00'
|
||||
LEFT_ARROW=b'\x00\x00 \x00\x10\x00\x08\x00\xf4?\x08\x00\x10\x00 \x00'
|
||||
RIGHT_ARROW=b'\x00\x00\x00\x04\x00\x08\x00\x10\xfc/\x00\x10\x00\x08\x00\x04'
|
||||
DRESS=b' \x02\xf0\x07`\x03\xc0\x01\xa0\x02P\x05\xa8\n\xf0\x07'
|
||||
TRANSFORMERS=b'\x00\x00\x80\x00`\x03\xa0\x02\xa0\x02@\x01@\x01 \x02'
|
||||
SCISSORS=b' \x08`\x0c\xc0\x06\x80\x03\x00\x01\xc0\x06\xa0\n@\x04'
|
||||
EXIT=b'\x00\x0c\x00\x07\x80\x0e@2\x00\x05@\t\x00\x11\x00 '
|
||||
TREE=b'\x80\x00\xc0\x01\xe0\x03\xf0\x07\xf8\x0f\x80\x00\x80\x00\x80\x00'
|
||||
PACMAN=b'\xf0\x03\x18\x04L\x02\x04\x01\x0c\x02\x18\x04\xf0\x03\x00\x00'
|
||||
TARGET=b'\x00\x00\x00\x00\x80\x03@\x04@\x05@\x04\x80\x03\x00\x00'
|
||||
TSHIRT=b' \x04\xd0\x0b\x08\x100\x0c \x04 \x04 \x04\xe0\x07'
|
||||
ROLLERSKATE=b'\xf0\x00\x90\x00\x90\x07\x10\x08\xf0\x0f(\x148\x1c\x00\x00'
|
||||
DUCK=b'\xe0\x00\x90\x01\x08\x01<\x01 \x7f \x10\xe0\x0f'
|
||||
HOUSE=b"\xfc?\x06`\x03\xc0\xe4'$$\xa4$$$$$"
|
||||
TORTOISE=b'\x80\x01\xa0\x05\xe0\x07\xe0\x07\xe0\x07\xc0\x03 \x04\x00\x00'
|
||||
BUTTERFLY=b'\x00\x00`\x0c\x90\x12\xe0\x0f\x80\x03@\x05\xa0\n`\x0c'
|
||||
STICKFIGURE=b'\x80\x00@\x01\x80\x00\xc0\x01\xa0\x02\x80\x00@\x01 \x02'
|
||||
GHOST=b'\xe0\x03\xb0\x06\xb0\x06\xf0\x07\xb0\x06P\x05\xf0\x0f\xf0\x1f'
|
||||
PITCHFORK=b'\x00\xf8\x00\x04\x00\x04\xff\xff\x00\x04\x00\x04\x00\xf8\x00\x00'
|
||||
MUSIC_QUAVERS=b'\x00\x00\x00\x00\x18\x86<O\xf2<a\x18\x00\x00\x00\x00'
|
||||
MUSIC_QUAVER=b'\xfe\x00\x01\x01\xff\x0f\x00\x1e\x00?\x00?\x00>\x00\x1c'
|
||||
MUSIC_CROTCHET=b'\x00\x00\xff\x0f\x00\x1e\x00?\x00?\x00>\x00\x1c\x00\x00'
|
||||
COW=b'\x08\x00\x1e\x00\xfa\x07\xfe\x0f\xfe70F0\x060\x06'
|
||||
RABBIT=b'\xc0?~@\x01Q>\\\x01Q~@\xc0?\x00\x00'
|
||||
SQUARE_SMALL=b'\x00\x00\x00\x00\xc0\x03@\x02@\x02\xc0\x03\x00\x00\x00\x00'
|
||||
SQUARE=b'\xf0\x0f\x10\x08\x10\x08\x10\x08\x10\x08\x10\x08\x10\x08\xf0\x0f'
|
||||
DIAMOND_SMALL=b'\x00\x00\x00\x00\xc0\x01\xa0\x02@\x01\x80\x00\x00\x00\x00\x00'
|
||||
DIAMOND=b'\xf0\x07X\r\xec\x1b\xd8\r\xb0\x06`\x03\xc0\x01\x80\x00'
|
||||
CHESSBOARD=b'\x00\x00\xf8?\xa8*\xf8?\xa8*\xf8?\xa8*\xf8?'
|
||||
TRIANGLE_LEFT=b'\x00\x00\x00\x01\x80\x01\xc0\x01\xe0\x01\xc0\x01\x80\x01\x00\x01'
|
||||
TRIANGLE=b'\x00\x00\x80\x01\xc0\x03\xe0\x07\xf0\x0f\xf8\x1f\xfc?\x00\x00'
|
||||
SNAKE=b'\x00\x0e\x00\n\x00\x0e\xf0\x03\xf8\x03\x1c\x00\x0e\x00\x00\x00'
|
||||
UMBRELLA=b'\x80\x00\xe0\x03\xf0\x07\xf8\x0f\x80\x00\x80\x00\x80\x02\x80\x03'
|
||||
SKULL=b'\xe0\x03\x90\x04\x88\x08x\x0f\xf0\x07 \x02\xa0\x02\xc0\x01'
|
||||
GIRAFFE=b'\x80\x01\x80\x03\x80\x00\x80\x00\x80\x00\xf0\x00\x90\x00\x90\x00'
|
||||
SWORD=b'\x00\x00\x10\x000\x00\xfc\x1f\xfc\x1f0\x00\x10\x00\x00\x00'
|
||||
DOOR_OPENING=b'\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff'
|
||||
DOOR_OPEN=b'\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff'
|
||||
DOOR_CLOSE=b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
|
||||
70
mixly/boards/default/micropython/build/lib/matrix32x12.py
Normal file
70
mixly/boards/default/micropython/build/lib/matrix32x12.py
Normal file
@@ -0,0 +1,70 @@
|
||||
"""
|
||||
Matrix Displays
|
||||
|
||||
Micropython library for the TM1680 Matrix Displays
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20230414
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
from tm1680 import TM1680
|
||||
|
||||
class Matrix(TM1680):
|
||||
"""A single matrix."""
|
||||
def __init__(self, i2c, address=0x72, brightness=0.3, font_address=0x3A0000, width=32, height=12):
|
||||
super().__init__(i2c, address, brightness, width, height)
|
||||
self.font(font_address)
|
||||
|
||||
"""Graph module"""
|
||||
HEART_SMALL=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x02\x00\x00p\x07\x00\x00\xf8\x0f\x00\x00\xf8\x0f\x00\x00\xf0\x07\x00\x00\xe0\x03\x00\x00\xc0\x01\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
HEART=b'\x00\x00\x00\x00\x00 \x02\x00\x00p\x07\x00\x00\xf8\x0f\x00\x00\xfc\x1f\x00\x00\xfc\x1f\x00\x00\xf8\x0f\x00\x00\xf0\x07\x00\x00\xe0\x03\x00\x00\xc0\x01\x00\x00\x80\x00\x00\x00\x00\x00\x00'
|
||||
HAPPY=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04 \x00\x00\x04 \x00\x00\x04 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x08\x00\x00 \x04\x00\x00@\x02\x00\x00\x80\x01\x00\x00\x00\x00\x00'
|
||||
SAD=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00@\x02\x00\x00 \x04\x00\x00\x10\x08\x00\x00\x00\x00\x00'
|
||||
SMILE=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04 \x00\x00\x0c0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c0\x00\x008\x1c\x00\x00\xe0\x07\x00\x00\x00\x00\x00'
|
||||
SILLY=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04 \x00\x00\x08\x10\x00\x00\x04 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x07\x00\x00 \x04\x00\x00@\x02\x00\x00\x80\x01\x00\x00\x00\x00\x00'
|
||||
FABULOUS=b'\x00\x00\x00\x00\x00\x04 \x00\x00\x08\x10\x00\x00\x0c0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x1f\x00\x00\x08\x10\x00\x00\x08\x10\x00\x00\x10\x08\x00\x00\xe0\x07\x00\x00\x00\x00\x00'
|
||||
SURPRISED=b'\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x00\x00\x00'
|
||||
ASLEEP=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x07\x00\x00\x10\x08\x00\x00\xe0\x07\x00\x00\x00\x00\x00'
|
||||
ANGRY=b'\x00\x00\x00\x00\x00 \x04\x00\x00\x10\x08\x00\x00\x08\x10\x00\x00\x04 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00@\x02\x00\x00 \x04\x00\x00\x10\x08\x00\x00\x08\x10\x00'
|
||||
CONFUSED=b'\x00\xc0\x03\x00\x00`\x06\x00\x000\x0c\x00\x000\x0c\x00\x00\x00\x0c\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x80\x01\x00'
|
||||
NO=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x08\x00\x00 \x04\x00\x00@\x02\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00@\x02\x00\x00 \x04\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
YES=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x00\x00\x00\x18\x00\x00\x00\x0c\x00\x00\x00\x06\x00\x00\x0c\x03\x00\x00\x98\x01\x00\x00\xf0\x00\x00\x00`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
LEFT_ARROW=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00 \x00\x00\x00\x10\x00\x00\x00\xe8\x1f\x00\x00\x10\x00\x00\x00 \x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
RIGHT_ARROW=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x08\x00\x00\xf8\x17\x00\x00\x00\x08\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
DRESS=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x02\x00\x00\xf0\x07\x00\x00`\x03\x00\x00\xc0\x01\x00\x00\xa0\x02\x00\x00P\x05\x00\x00\xa8\n\x00\x00\xf0\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
TRANSFORMERS=b'\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\xc0\x06\x00\x00@\x05\x00\x00@\x05\x00\x00@\x05\x00\x00\x80\x02\x00\x00\x80\x02\x00\x00@\x04\x00\x00 \x08\x00\x00\x00\x00\x00'
|
||||
SCISSORS=b'\x00\x00\x00\x00\x00\x04\x10\x00\x00\x0c\x18\x00\x00\x18\x0c\x00\x000\x06\x00\x00`\x03\x00\x00\xc0\x01\x00\x00\x80\x00\x00\x00p\x07\x00\x00H\t\x00\x00H\t\x00\x000\x06\x00'
|
||||
EXIT=b'\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\xc0\x01\x00\x00\xa0\x03\x00\x00\x90\x0c\x00\x00\x80\x00\x00\x00P\x01\x00\x00@\x02\x00\x00@\x04\x00\x00\x00\x08\x00\x00\x00\x00\x00'
|
||||
TREE=b'\x00\x00\x00\x00\x00\x80\x00\x00\x00\xc0\x01\x00\x00\xe0\x03\x00\x00\xf0\x07\x00\x00\xf8\x0f\x00\x00\xfc\x1f\x00\x00\x80\x00\x00\x00\x80\x00\x00\x00\x80\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00'
|
||||
PACMAN=b'\x00\x00\x00\x00\x00\xf0\x07\x00\x00\x18\x08\x00\x00\x8c\x04\x00\x00\x0c\x02\x00\x00\x04\x01\x00\x00\x0c\x02\x00\x00\x0c\x04\x00\x00\x18\x08\x00\x00\xf0\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
TARGET=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x07\x00\x00 \x08\x00\x00 \x08\x00\x00 \t\x00\x00 \x08\x00\x00 \x08\x00\x00\xc0\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
TSHIRT=b'\x00@\x04\x00\x00\xa0\x0b\x00\x00\x10\x10\x00\x00\x08 \x00\x000\x18\x00\x00 \x08\x00\x00 \x08\x00\x00 \x08\x00\x00 \x08\x00\x00 \x08\x00\x00\xe0\x0f\x00\x00\x00\x00\x00'
|
||||
ROLLERSKATE=b'\x00\x00\x00\x00\x00\xf8\x00\x00\x00\x88\x00\x00\x00\x88\x00\x00\x00\x88\x0f\x00\x00\x08\x10\x00\x00\x08\x10\x00\x00\xf8\x1f\x00\x00\x14(\x00\x00\x1c8\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
DUCK=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x90\x00\x00\x00\x08\x01\x00\x00<\x01\x00\x00 ?\x00\x00 \x10\x00\x00 \x08\x00\x00\xe0\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
HOUSE=b'\x00\x00\x00\x00\x00\xf0\x0f\x00\x00\x18\x18\x00\x00\x0c0\x00\x00\xd0\x0b\x00\x00P\n\x00\x00P\n\x00\x00\xd0\n\x00\x00P\n\x00\x00P\n\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
TORTOISE=b'\x00\x00\x00\x00\x00\x80\x01\x00\x00\xa0\x05\x00\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xc0\x03\x00\x00 \x04\x00\x00\x00\x00\x00'
|
||||
BUTTERFLY=b'\x00\x00\x00\x00\x00\x18\x0c\x00\x00$\x12\x00\x00D\x11\x00\x00\xf8\x0f\x00\x00\xc0\x01\x00\x00\xa0\x02\x00\x00\xd0\x05\x00\x00(\n\x00\x00\x18\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
STICKFIGURE=b'\x00\x80\x00\x00\x00@\x01\x00\x00@\x01\x00\x00\x80\x00\x00\x00\x80\x00\x00\x00\xc0\x01\x00\x00\xa0\x02\x00\x00\x90\x04\x00\x00@\x01\x00\x00 \x02\x00\x00\x10\x04\x00\x00\x00\x00\x00'
|
||||
GHOST=b'\x00\x00\x00\x00\x00\xe0\x03\x00\x00\xb0\x06\x00\x00\xb0\x06\x00\x00\xb0\x06\x00\x00\xf0\x07\x00\x00\xb0\x06\x00\x00\xb0\x06\x00\x00P\x05\x00\x00\xf0\x0f\x00\x00\xf0\x1f\x00\x00\x00\x00\x00'
|
||||
PITCHFORK=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\xfc?\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
MUSIC_QUAVERS=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x06\x00\x00x\x0f\x00\x00\xe4=\x00\x00\xc0\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
MUSIC_QUAVER=b'\x00\x00\x03\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00`\x01\x00\x00\xf0\x01\x00\x00\xf8\x01\x00\x00\xf8\x00\x00\x00p\x00\x00'
|
||||
MUSIC_CROTCHET=b'\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00`\x01\x00\x00\xf0\x01\x00\x00\xf8\x01\x00\x00\xf8\x00\x00\x00p\x00\x00'
|
||||
COW=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00x\x00\x00\x00\xe8\x0f\x00\x00\xf8\x1f\x00\x00\xf8/\x00\x00`,\x00\x00`\x0c\x00\x00`\x0c\x00\x00`\x0c\x00\x00\x00\x00\x00'
|
||||
RABBIT=b'\x00@\x01\x00\x00\xa0\x02\x00\x00\xa0\x02\x00\x00\xa0\x02\x00\x00\xa0\x02\x00\x000\x06\x00\x00\x10\x04\x00\x00P\x05\x00\x00\x10\x04\x00\x00\x90\x04\x00\x00\xd0\x05\x00\x00\xe0\x03\x00'
|
||||
SQUARE_SMALL=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x03\x00\x00@\x02\x00\x00@\x02\x00\x00\xc0\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
SQUARE=b'\x00\xfc?\x00\x00\x04 \x00\x00\x04 \x00\x00\x04 \x00\x00\x04 \x00\x00\x04 \x00\x00\x04 \x00\x00\x04 \x00\x00\x04 \x00\x00\x04 \x00\x00\x04 \x00\x00\xfc?\x00'
|
||||
DIAMOND_SMALL=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x01\x00\x00\xa0\x02\x00\x00@\x01\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
DIAMOND=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x07\x00\x00X\r\x00\x00\xec\x1b\x00\x00\xd8\r\x00\x00\xb0\x06\x00\x00`\x03\x00\x00\xc0\x01\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
CHESSBOARD=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\x1f\x00\x00T\x15\x00\x00\xfc\x1f\x00\x00T\x15\x00\x00\xfc\x1f\x00\x00T\x15\x00\x00\xfc\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
TRIANGLE_LEFT=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x80\x03\x00\x00\xc0\x03\x00\x00\x80\x03\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
TRIANGLE=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\xc0\x03\x00\x00\xe0\x07\x00\x00\xf0\x0f\x00\x00\xf8\x1f\x00\x00\xfc?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
SNAKE=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00(\x00\x00\x008\x00\x00\xc0\x0f\x00\x00\xe0\x0f\x00\x00p\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
UMBRELLA=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\xe0\x03\x00\x00\xf0\x07\x00\x00\xf8\x0f\x00\x00\x80\x00\x00\x00\x80\x00\x00\x00\x80\x00\x00\x00\x80\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00'
|
||||
SKULL=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x03\x00\x00\x90\x04\x00\x00\x88\x08\x00\x00x\x0f\x00\x00\xf0\x07\x00\x00 \x02\x00\x00 \x02\x00\x00\xa0\x02\x00\x00\xc0\x01\x00\x00\x00\x00\x00'
|
||||
GIRAFFE=b'\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\xe0\x01\x00\x00 \x01\x00\x00 \x01\x00\x00 \x01\x00'
|
||||
SWORD=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x000\x00\x00\x00\xfc\x1f\x00\x00\xfc\x1f\x00\x000\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
DOOR_OPEN=b'\x00\xf8\x1f\x00\x00\x04 \x00\x00\x0c \x00\x00\x1c \x00\x00\x1c \x00\x00\x1c \x00\x00\x1c \x00\x00\x1c \x00\x00\x1c \x00\x00\x1c \x00\x00\x1c \x00\x00\x1c \x00'
|
||||
DOOR_OPENING=b'\x00\xf8\x1f\x00\x004 \x00\x00L \x00\x00\x8c \x00\x00\x0c!\x00\x00\x0c!\x00\x00L!\x00\x00L!\x00\x00\x0c!\x00\x00\x0c!\x00\x00\x0c!\x00\x00\x0c!\x00'
|
||||
DOOR_CLOSE=b'\x00\xf8\x1f\x00\x00\xf4/\x00\x00\x0c0\x00\x00\x0c0\x00\x00\x0c0\x00\x00\x0c0\x00\x00\x0c0\x00\x00\x0c6\x00\x00\x0c0\x00\x00\x0c0\x00\x00\x0c0\x00\x00\x0c0\x00'
|
||||
67
mixly/boards/default/micropython/build/lib/matrix8x5.py
Normal file
67
mixly/boards/default/micropython/build/lib/matrix8x5.py
Normal file
@@ -0,0 +1,67 @@
|
||||
"""
|
||||
Matrix8x5 Displays
|
||||
|
||||
Micropython library for the TM1652 Matrix8x5 Displays
|
||||
=======================================================
|
||||
|
||||
#Preliminary compositio 20230411
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
from tm1652 import TM1652
|
||||
|
||||
class Matrix(TM1652):
|
||||
"""A single matrix."""
|
||||
def __init__(self, pin, brightness=0.3, font="4x5", width=8, height=5):
|
||||
super().__init__(pin, brightness, width, height)
|
||||
self.font(font)
|
||||
|
||||
"""Graph module 5x8"""
|
||||
HEART = b'\x14>>\x1c\x08'
|
||||
HEART_SMALL = b'\x00\x14\x1c\x08\x00'
|
||||
HAPPY = b'\x00\x14\x00"\x1c'
|
||||
SAD = b'\x00\x14\x00\x1c"'
|
||||
SMILE = b'\x00\x14\x00"\x1c'
|
||||
SILLY = b'"\x00>(8'
|
||||
FABULOUS = b'>6\x00\x14\x1c'
|
||||
SURPRISED = b'\x14\x00\x08\x14\x08'
|
||||
ASLEEP = b'\x006\x00\x1c\x00'
|
||||
ANGRY = b'"\x14\x00>*'
|
||||
CONFUSED = b'\x00\x14\x00\x14*'
|
||||
NO = b'"\x14\x08\x14"'
|
||||
YES = b'\x00 \x10\n\x04'
|
||||
LEFT_ARROW = b'\x08\x04~\x04\x08'
|
||||
RIGHT_ARROW = b'\x10 ~ \x10'
|
||||
DRESS = b'$f<Z\xbd'
|
||||
TRANSFORMERS = b'\x08\x1c*\x14"'
|
||||
SCISSORS = b'&\x16\x08\x16&'
|
||||
EXIT = b'\x08\x1c*\x16 '
|
||||
TREE = b'\x08\x1c>\x08\x08'
|
||||
PACMAN = b'<\x16\x0e\x1e<'
|
||||
TARGET = b'\x08\x1c6\x1c\x08'
|
||||
TSHIRT = b'6>\x1c\x1c\x1c'
|
||||
ROLLERSKATE = b'00>>\x14'
|
||||
DUCK = b'\x0c\x0e<\x1c\x00'
|
||||
HOUSE = b'\x08\x1c>\x1c\x14'
|
||||
TORTOISE = b'\x00\x1c>\x14\x00'
|
||||
BUTTERFLY = b'6>\x08>6'
|
||||
STICKFIGURE = b'\x08>\x08\x14"'
|
||||
GHOST = b'>*>>*'
|
||||
PITCHFORK = b'**>\x08\x08'
|
||||
MUSIC_QUAVERS = b'<$$66'
|
||||
MUSIC_QUAVER = b'\x08\x18(\x0e\x0e'
|
||||
MUSIC_CROTCHET = b'\x08\x08\x08\x0e\x0e'
|
||||
COW = b'"">\x1c\x08'
|
||||
RABBIT = b'\n\n\x1e\x16\x1e'
|
||||
SQUARE_SMALL = b'\x00\x1c\x14\x1c\x00'
|
||||
SQUARE = b'>""">'
|
||||
DIAMOND_SMALL = b'\x00\x08\x14\x08\x00'
|
||||
DIAMOND = b'\x08\x14"\x14\x08'
|
||||
CHESSBOARD = b'\x14*\x14*\x14'
|
||||
TRIANGLE_LEFT = b'\x02\x06\n\x12>'
|
||||
TRIANGLE = b'\x00\x08\x14>\x00'
|
||||
SNAKE = b'\x066\x14\x1c\x00'
|
||||
UMBRELLA = b'\x1c>\x08\n\x0c'
|
||||
SKULL = b'\x1c*>\x1c\x1c'
|
||||
GIRAFFE = b'\x06\x04\x04\x1c\x14'
|
||||
SWORD = b'\x08\x08\x08\x1c\x08'
|
||||
291
mixly/boards/default/micropython/build/lib/max30102.py
Normal file
291
mixly/boards/default/micropython/build/lib/max30102.py
Normal file
@@ -0,0 +1,291 @@
|
||||
"""
|
||||
MAX30102
|
||||
|
||||
MicroPython library for the MAX30102(bmp_and_spo2)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20220723
|
||||
#base on https://github.com/doug-burrell/max30102.git 20220723
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
# Address of each register.
|
||||
REG_INTR_STATUS_1 = const(0x00)
|
||||
REG_INTR_STATUS_2 = const(0x01)
|
||||
REG_INTR_ENABLE_1 = const(0x02)
|
||||
REG_INTR_ENABLE_2 = const(0x03)
|
||||
REG_FIFO_WR_PTR = const(0x04)
|
||||
REG_OVF_COUNTER = const(0x05)
|
||||
REG_FIFO_RD_PTR = const(0x06)
|
||||
REG_FIFO_DATA = const(0x07)
|
||||
REG_FIFO_CONFIG = const(0x08)
|
||||
REG_MODE_CONFIG = const(0x09)
|
||||
REG_SPO2_CONFIG = const(0x0A)
|
||||
REG_LED1_PA = const(0x0C)
|
||||
REG_LED2_PA = const(0x0D)
|
||||
REG_PILOT_PA = const(0x10)
|
||||
REG_MULTI_LED_CTRL1 = const(0x11)
|
||||
REG_MULTI_LED_CTRL2 = const(0x12)
|
||||
REG_TEMP_INTR = const(0x1F)
|
||||
REG_TEMP_FRAC = const(0x20)
|
||||
REG_TEMP_CONFIG = const(0x21)
|
||||
REG_PART_ID = const(0xFF)
|
||||
|
||||
class MAX30102:
|
||||
def __init__(self, i2c, address=0x57):
|
||||
"""Initiate MAX30102 class ond each function responsible for correct device start-up"""
|
||||
self._device = i2c
|
||||
self._address = address
|
||||
|
||||
if self._chip_id() != 0x15:
|
||||
raise AttributeError("Cannot find a MAX30102")
|
||||
|
||||
self.reset()
|
||||
time.sleep(1)
|
||||
self.setup()
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg,nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _chip_id(self):
|
||||
return self._rreg(REG_PART_ID)
|
||||
|
||||
def reset(self):
|
||||
"""Set default values of all registers"""
|
||||
self._wreg(REG_MODE_CONFIG, 0x40)
|
||||
|
||||
def shutdown(self):
|
||||
"""Shutdown the device"""
|
||||
self._wreg(mode_config, 0x80) # 0b10000000 = 0x80
|
||||
|
||||
def setup(self,led_mode=0x03):
|
||||
"""Set all registers needed to correct work of sensor"""
|
||||
self._wreg(REG_INTR_ENABLE_1, 0xC0) # 0xc0 : A_FULL_EN and PPG_RDY_EN = Interrupt will be triggered when
|
||||
self._wreg(REG_INTR_ENABLE_2, 0x00) # fifo almost full & new fifo data ready
|
||||
|
||||
self._wreg(REG_FIFO_WR_PTR, 0x00) # FIFO_WR_PTR[4:0]
|
||||
self._wreg(REG_OVF_COUNTER, 0x00) # OVF_COUNTER[4:0]
|
||||
self._wreg(REG_FIFO_RD_PTR, 0x00) # FIFO_RD_PTR[4:0]
|
||||
|
||||
self._wreg(REG_FIFO_CONFIG, 0x4F) # sample avg = 4, fifo rollover = false, fifo almost full = 17
|
||||
self._wreg(REG_MODE_CONFIG, led_mode) # 0x02 for read-only, 0x03 for SpO2 mode, 0x07 multimode LED
|
||||
self._wreg(REG_SPO2_CONFIG, 0x27) # SPO2_ADC range = 4096nA, SPO2 sample rate = 100Hz, LED pulse-width = 411uS
|
||||
|
||||
self._wreg(REG_LED1_PA, 0x40) # choose value for ~7mA for LED1
|
||||
self._wreg(REG_LED2_PA, 0x40) # choose value for ~7mA for LED2
|
||||
self._wreg(REG_PILOT_PA, 0x7F) # choose value fro ~25mA for Pilot LED
|
||||
|
||||
def get_data_present(self):
|
||||
read_ptr = self._rreg(REG_FIFO_RD_PTR)
|
||||
write_ptr = self._rreg(REG_FIFO_WR_PTR)
|
||||
if read_ptr == write_ptr:
|
||||
return 0
|
||||
else:
|
||||
num_samples = write_ptr - read_ptr # account for pointer wrap around
|
||||
if num_samples < 0:
|
||||
num_samples += 32
|
||||
return num_samples
|
||||
|
||||
def read_fifo(self):
|
||||
"""This function will read the data register"""
|
||||
reg_INTR1 = self._rreg(REG_INTR_STATUS_1)
|
||||
reg_INTR2 = self._rreg(REG_INTR_STATUS_2)
|
||||
d = self._rreg(REG_FIFO_DATA, 6)
|
||||
|
||||
red_led = (d[0] << 16 | d[1] << 8 | d[2]) & 0x03FFFF
|
||||
ir_led = (d[3] << 16 | d[4] << 8 | d[5]) & 0x03FFFF
|
||||
return ir_led,red_led
|
||||
|
||||
def read_sequential(self, amount=100):
|
||||
"""This function will read the red-led and ir-led `amount` times"""
|
||||
red_buf = []
|
||||
ir_buf = []
|
||||
count = amount
|
||||
while count > 0:
|
||||
num_bytes = self.get_data_present()
|
||||
while num_bytes > 0:
|
||||
ir, red = self.read_fifo()
|
||||
red_buf.append(red)
|
||||
ir_buf.append(ir)
|
||||
num_bytes -= 1
|
||||
count -= 1
|
||||
return ir_buf,red_buf
|
||||
|
||||
def temperature(self):
|
||||
"""Read temperature as sum of integer and fraction value """
|
||||
self._wreg(REG_TEMP_CONFIG, 0x01)
|
||||
status = self._rreg(REG_INTR_STATUS_2)
|
||||
count = 1
|
||||
while status != 2 and count < 5:
|
||||
status = self._rreg(REG_INTR_STATUS_2)
|
||||
count += 1
|
||||
integer = self._rreg(REG_TEMP_INTR)
|
||||
fraction = self._rreg(REG_TEMP_FRAC)
|
||||
return round(integer + fraction * 0.0625,2)
|
||||
|
||||
def heartrate(self,amount=5):
|
||||
bpms = []
|
||||
sop2 = []
|
||||
for _ in range(amount):
|
||||
ir_data, red_data=self.read_sequential()
|
||||
if get_mean(ir_data) < 50000 and get_mean(red_data) < 50000 :
|
||||
return 0,0
|
||||
raw_bpm, valid_bpm, raw_spo2, valid_spo2 = calc_hr_and_spo2(ir_data, red_data)
|
||||
if valid_bpm:
|
||||
bpms.append(raw_bpm)
|
||||
if valid_spo2:
|
||||
sop2.append(raw_spo2)
|
||||
bpms_len=len(bpms)
|
||||
sop2_len=len(sop2)
|
||||
if bpms_len<=2 or sop2_len<=2:
|
||||
return 0,0
|
||||
else:
|
||||
return sum(sorted(bpms)[1:bpms_len-1])//(bpms_len-2),round(sum(sorted(sop2)[1:sop2_len-1])/(sop2_len-2),2)
|
||||
|
||||
"""-----------以下心率算法-----------"""
|
||||
|
||||
SAMPLE_FREQ = 25 # 25 samples per second
|
||||
MA_SIZE = 4
|
||||
BUFFER_SIZE = 100 # sampling frequency * 4
|
||||
|
||||
def get_mean(ls):
|
||||
return sum(ls)/len(ls)
|
||||
|
||||
def calc_hr_and_spo2(ir_data, red_data):
|
||||
ir_mean = int(get_mean(ir_data))
|
||||
x = []
|
||||
for k in ir_data:
|
||||
x.append((k-ir_mean)*-1)
|
||||
for i in range(len(x) - MA_SIZE):
|
||||
x[i] = sum(x[i:i+MA_SIZE]) / MA_SIZE
|
||||
|
||||
n_th = int(get_mean(x))
|
||||
n_th = 30 if n_th < 30 else n_th # min allowed
|
||||
n_th = 60 if n_th > 60 else n_th # max allowed
|
||||
|
||||
ir_valley_locs, n_peaks = find_peaks(x, BUFFER_SIZE, n_th, 4, 15)
|
||||
peak_interval_sum = 0
|
||||
if n_peaks >= 2:
|
||||
for i in range(1, n_peaks):
|
||||
peak_interval_sum += (ir_valley_locs[i] - ir_valley_locs[i-1])
|
||||
peak_interval_sum = int(peak_interval_sum / (n_peaks - 1))
|
||||
hr = int(SAMPLE_FREQ * 60 / peak_interval_sum)
|
||||
hr_valid = True
|
||||
else:
|
||||
hr = -999
|
||||
hr_valid = False
|
||||
|
||||
exact_ir_valley_locs_count = n_peaks
|
||||
for i in range(exact_ir_valley_locs_count):
|
||||
if ir_valley_locs[i] > BUFFER_SIZE:
|
||||
spo2 = -999
|
||||
spo2_valid = False
|
||||
return hr, hr_valid, spo2, spo2_valid
|
||||
i_ratio_count = 0
|
||||
ratio = []
|
||||
# find max between two valley locations
|
||||
red_dc_max_index = -1
|
||||
ir_dc_max_index = -1
|
||||
for k in range(exact_ir_valley_locs_count-1):
|
||||
red_dc_max = -16777216
|
||||
ir_dc_max = -16777216
|
||||
if ir_valley_locs[k+1] - ir_valley_locs[k] > 3:
|
||||
for i in range(ir_valley_locs[k], ir_valley_locs[k+1]):
|
||||
if ir_data[i] > ir_dc_max:
|
||||
ir_dc_max = ir_data[i]
|
||||
ir_dc_max_index = i
|
||||
if red_data[i] > red_dc_max:
|
||||
red_dc_max = red_data[i]
|
||||
red_dc_max_index = i
|
||||
|
||||
red_ac = int((red_data[ir_valley_locs[k+1]] - red_data[ir_valley_locs[k]]) * (red_dc_max_index - ir_valley_locs[k]))
|
||||
red_ac = red_data[ir_valley_locs[k]] + int(red_ac / (ir_valley_locs[k+1] - ir_valley_locs[k]))
|
||||
red_ac = red_data[red_dc_max_index] - red_ac # subtract linear DC components from raw
|
||||
|
||||
ir_ac = int((ir_data[ir_valley_locs[k+1]] - ir_data[ir_valley_locs[k]]) * (ir_dc_max_index - ir_valley_locs[k]))
|
||||
ir_ac = ir_data[ir_valley_locs[k]] + int(ir_ac / (ir_valley_locs[k+1] - ir_valley_locs[k]))
|
||||
ir_ac = ir_data[ir_dc_max_index] - ir_ac # subtract linear DC components from raw
|
||||
|
||||
nume = red_ac * ir_dc_max
|
||||
denom = ir_ac * red_dc_max
|
||||
if (denom > 0 and i_ratio_count < 5) and nume != 0:
|
||||
ratio.append(int(((nume * 100) & 0xffffffff) / denom))
|
||||
i_ratio_count += 1
|
||||
# choose median value since PPG signal may vary from beat to beat
|
||||
ratio = sorted(ratio) # sort to ascending order
|
||||
mid_index = int(i_ratio_count / 2)
|
||||
|
||||
ratio_ave = 0
|
||||
if mid_index > 1:
|
||||
ratio_ave = int((ratio[mid_index-1] + ratio[mid_index])/2)
|
||||
else:
|
||||
if len(ratio) != 0:
|
||||
ratio_ave = ratio[mid_index]
|
||||
|
||||
if ratio_ave > 2 and ratio_ave < 184:
|
||||
# -45.060 * ratioAverage * ratioAverage / 10000 + 30.354 * ratioAverage / 100 + 94.845
|
||||
spo2 = -45.060 * (ratio_ave**2) / 10000.0 + 30.054 * ratio_ave / 100.0 + 94.845
|
||||
spo2_valid = True
|
||||
else:
|
||||
spo2 = -999
|
||||
spo2_valid = False
|
||||
|
||||
return hr, hr_valid, spo2, spo2_valid
|
||||
|
||||
def find_peaks(x, size, min_height, min_dist, max_num):
|
||||
""" Find at most MAX_NUM peaks above MIN_HEIGHT separated by at least MIN_DISTANCE"""
|
||||
ir_valley_locs, n_peaks = find_peaks_above_min_height(x, size, min_height, max_num)
|
||||
ir_valley_locs, n_peaks = remove_close_peaks(n_peaks, ir_valley_locs, x, min_dist)
|
||||
n_peaks = min([n_peaks, max_num])
|
||||
return ir_valley_locs, n_peaks
|
||||
|
||||
def find_peaks_above_min_height(x, size, min_height, max_num):
|
||||
"""Find all peaks above MIN_HEIGHT """
|
||||
i = 0
|
||||
n_peaks = 0
|
||||
ir_valley_locs = [] # [0 for i in range(max_num)]
|
||||
while i < size - 1:
|
||||
if x[i] > min_height and x[i] > x[i-1]: # find the left edge of potential peaks
|
||||
n_width = 1
|
||||
while i + n_width < size - 1 and x[i] == x[i+n_width]: # find flat peaks
|
||||
n_width += 1
|
||||
if x[i] > x[i+n_width] and n_peaks < max_num: # find the right edge of peaks
|
||||
ir_valley_locs.append(i)
|
||||
n_peaks += 1 # original uses post increment
|
||||
i += n_width + 1
|
||||
else:
|
||||
i += n_width
|
||||
else:
|
||||
i += 1
|
||||
|
||||
return ir_valley_locs, n_peaks
|
||||
|
||||
def remove_close_peaks(n_peaks, ir_valley_locs, x, min_dist):
|
||||
""" Remove peaks separated by less than MIN_DISTANCE"""
|
||||
sorted_indices = sorted(ir_valley_locs, key=lambda i: x[i])
|
||||
sorted_indices.reverse()
|
||||
|
||||
i = -1
|
||||
while i < n_peaks:
|
||||
old_n_peaks = n_peaks
|
||||
n_peaks = i + 1
|
||||
j = i + 1
|
||||
while j < old_n_peaks:
|
||||
n_dist = (sorted_indices[j] - sorted_indices[i]) if i != -1 else (sorted_indices[j] + 1) # lag-zero peak of autocorr is at index -1
|
||||
if n_dist > min_dist or n_dist < -1 * min_dist:
|
||||
sorted_indices[n_peaks] = sorted_indices[j]
|
||||
n_peaks += 1 # original uses post increment
|
||||
j += 1
|
||||
i += 1
|
||||
|
||||
sorted_indices[:n_peaks] = sorted(sorted_indices[:n_peaks])
|
||||
return sorted_indices, n_peaks
|
||||
206
mixly/boards/default/micropython/build/lib/mixgo_ai.py
Normal file
206
mixly/boards/default/micropython/build/lib/mixgo_ai.py
Normal file
@@ -0,0 +1,206 @@
|
||||
"""
|
||||
AI COM
|
||||
|
||||
MicroPython library for the AI COM ( for MixGo AI)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20220905
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import time,gc
|
||||
|
||||
|
||||
class INFO:
|
||||
def __init__(self, info1,info2,rect):
|
||||
self.info1=info1
|
||||
self.info2=info2
|
||||
self.rect=rect
|
||||
self.x=None
|
||||
self.y=None
|
||||
self.w=None
|
||||
self.h=None
|
||||
self.xc=None
|
||||
self.yc=None
|
||||
if type(rect) in [tuple,list]:
|
||||
self.x=rect[0]
|
||||
self.y=rect[1]
|
||||
self.w=rect[2]
|
||||
self.h=rect[3]
|
||||
self.xc=rect[0]+rect[2]//2
|
||||
self.yc=rect[1]+rect[3]//2
|
||||
self.type="info"
|
||||
|
||||
class AI:
|
||||
def __init__(self, uart, quick=False):
|
||||
self._uart=uart
|
||||
self._uart.init(baudrate=115200, timeout=500)
|
||||
self._info=[]
|
||||
self._sdata=[]
|
||||
self._removal=quick
|
||||
if not self._chip_id():
|
||||
raise AttributeError("Cannot find a MixGo AI")
|
||||
|
||||
def send(self,data):
|
||||
eec=0
|
||||
buffer=str(data).encode()
|
||||
for i in range(len(buffer)):
|
||||
eec^=int(buffer[i])
|
||||
eec=0 if eec==10 else eec
|
||||
self._uart.write(buffer+chr(eec)+b'\n')
|
||||
|
||||
def recv(self,timeout=500,warn=True):
|
||||
t_star=time.ticks_ms()
|
||||
while not self._uart.any():
|
||||
if time.ticks_diff(time.ticks_ms(), t_star) >timeout:
|
||||
if warn:
|
||||
print("Warning: MixGo AI timeout not responding")
|
||||
return False
|
||||
buffer = self._uart.readline()
|
||||
if buffer:
|
||||
eec=0
|
||||
if len(buffer)>=3:
|
||||
for i in range(len(buffer)-2):
|
||||
eec^=int(buffer[i])
|
||||
if eec==buffer[-2] or buffer[-2]==0:
|
||||
try:
|
||||
return eval(buffer[:-2].decode())
|
||||
except:
|
||||
return None
|
||||
def _chip_id(self):
|
||||
for _ in range(10):
|
||||
self.send(["ok",[[],'']])
|
||||
if self.recv(1000,False):
|
||||
return True
|
||||
|
||||
def request(self,func='', para=[], name=None, timeout=1000):
|
||||
if self._sdata != para:
|
||||
self._sdata=para if self._removal else None
|
||||
self.send([func,[para,name]])
|
||||
else:
|
||||
self.send([func,[[],name]])
|
||||
|
||||
#print(func)
|
||||
if func in ['ailr','ailt','play','record','asr']: #不需要警告提醒
|
||||
data=self.recv(timeout,False)
|
||||
else:
|
||||
data=self.recv(timeout,True)
|
||||
|
||||
self._info=[]
|
||||
if data:
|
||||
#报错处理
|
||||
if "err" in data[0] and type(data[1])==list:
|
||||
if type(data[1][0]) == IndexError or "Missing parameter" == data[1][0]:
|
||||
self.send(["ok",[[],name]]) #恢复出厂
|
||||
self.send([func,[para,name]]) #在发送参数
|
||||
else:
|
||||
raise RuntimeError("Error from MixGo AI",data[1][0])
|
||||
else:
|
||||
_len=max(len(data[0]),len(data[1]))
|
||||
for i in range(_len):
|
||||
if type(data[0][i]) == list:
|
||||
info1=data[0][i][0]
|
||||
info2=data[0][i][1]
|
||||
else:
|
||||
info1=data[0][i]
|
||||
info2=None
|
||||
|
||||
if data[1]:
|
||||
rect=data[1][i]
|
||||
else:
|
||||
rect=None
|
||||
self._info.append(INFO(info1,info2,rect))
|
||||
return self._info
|
||||
|
||||
def info_len(self):
|
||||
return len(self._info)
|
||||
|
||||
def info_number(self,number):
|
||||
if self.info_len() > number:
|
||||
return self._info[number]
|
||||
|
||||
def configure(self, tx_pin, rx_pin, restart=False):
|
||||
info=self.request('start',para=[["uart",tx_pin,rx_pin],restart])
|
||||
return info[0].info1 if info else False
|
||||
|
||||
def find_qrcode(self):
|
||||
info=self.request('qr')
|
||||
return (info[0].info1,info[0].rect) if info else (None,None)
|
||||
|
||||
def find_barcode(self):
|
||||
info=self.request('bar')
|
||||
return (info[0].info1,info[0].rect) if info else (None,None)
|
||||
|
||||
def find_apriltag(self):
|
||||
info=self.request('tag')
|
||||
return (info[0].info1,info[0].rect) if info else (None,None)
|
||||
|
||||
def find_qrcodes(self):
|
||||
return self.request('qr')
|
||||
|
||||
def find_barcodes(self):
|
||||
return self.request('bar')
|
||||
|
||||
def find_apriltags(self):
|
||||
return self.request('tag')
|
||||
|
||||
def find_lines(self, threshold=2500, theta_margin=25, rho_margin=25):
|
||||
return self.request('line', para=[threshold, theta_margin, rho_margin])
|
||||
|
||||
def find_circles(self, threshold=2500, r_min=2, r_max=100):
|
||||
return self.request('circle', para=[threshold, r_min, r_max])
|
||||
|
||||
def find_rects(self, threshold=2500):
|
||||
return self.request('rect', para=[threshold])
|
||||
|
||||
def find_colors(self, scale=2):
|
||||
info=self.request('color', para=[scale])
|
||||
if info:
|
||||
return info[0].info1,info[0].info2
|
||||
else:
|
||||
return None,None
|
||||
|
||||
def color_track(self, lab=[0, 100, 0, 100, 0, 0], pixels_threshold=10, margin=1):
|
||||
return self.request('ctrace', para=[lab, pixels_threshold, margin])
|
||||
|
||||
def ailocal_train(self, lsit_names, path="mixgo", number=5, disname='自模型训练'):
|
||||
info= self.request('ailt', para=[lsit_names, path, number], name=disname)
|
||||
return info[0].info1 if info else False
|
||||
|
||||
def ailocal_class(self, lsit_names, path="mixgo", disname='自模型识别'):
|
||||
return self.request('ailr', para=[lsit_names, path], name=disname)
|
||||
|
||||
def yolo_recognize(self, anchor, path, disname='物品识别'):
|
||||
return self.request('aild', para=[anchor, path], name=disname)
|
||||
|
||||
def led_rgb(self, rgb1=(0,0,0), rgb2=(0,0,0)):
|
||||
info= self.request('rgb', para=[rgb1, rgb2])
|
||||
return info[0].info1 if info else False
|
||||
|
||||
def audio_play(self, bck_pin=12, ws_pin=13, dat_pin=14, path="mixgo.wav", volume=80):
|
||||
info= self.request('play', para=[[bck_pin, ws_pin, dat_pin], path, volume])
|
||||
return info[0].info1 if info else False
|
||||
|
||||
def audio_record(self, sample_rate=16000, path="mixgo.wav", times=5):
|
||||
info= self.request('record', para=[sample_rate, path, times])
|
||||
return info[0].info1 if info else False
|
||||
|
||||
def asr_recognize(self, corpus,threshold=0.1):
|
||||
clist=[]
|
||||
for cor in corpus:
|
||||
clist.append([cor,threshold])
|
||||
info=self.request('asr', para=[dict(clist)])
|
||||
if info:
|
||||
return info[0].info1,info[0].info2
|
||||
else:
|
||||
return None,None
|
||||
|
||||
def find_licenseplate(self):
|
||||
return self.request('alpr')
|
||||
|
||||
def find_20object(self):
|
||||
return self.request('voc20')
|
||||
|
||||
def face_detect(self):
|
||||
return self.request('face_d')
|
||||
353
mixly/boards/default/micropython/build/lib/mixiot.py
Normal file
353
mixly/boards/default/micropython/build/lib/mixiot.py
Normal file
@@ -0,0 +1,353 @@
|
||||
import time
|
||||
import usocket as socket
|
||||
import ustruct as struct
|
||||
from machine import unique_id
|
||||
from ubinascii import hexlify
|
||||
from matcher import MQTTMatcher
|
||||
|
||||
ADDITIONAL_TOPIC = 'b640a0ce465fa2a4150c36b305c1c11b'
|
||||
WILL_TOPIC = '9d634e1a156dc0c1611eb4c3cff57276'
|
||||
|
||||
def wlan_connect(ssid='MYSSID', password='MYPASS', timeout=10):
|
||||
import network
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
if not wlan.active():
|
||||
wlan.active(True)
|
||||
time.sleep(0.5)
|
||||
if not wlan.isconnected():
|
||||
print('connecting to:', ssid, end ="")
|
||||
try:
|
||||
wlan.connect(ssid, password)
|
||||
except:
|
||||
pass
|
||||
_num = 0
|
||||
while not wlan.isconnected():
|
||||
_num += 1
|
||||
time.sleep(1)
|
||||
print('.',end ="")
|
||||
if _num > timeout:
|
||||
wlan.active(False)
|
||||
print('')
|
||||
import os
|
||||
if 'c5' in os.uname().machine.lower():
|
||||
raise RuntimeError("WiFi connection timeout. Please check the SSID and password")
|
||||
else:
|
||||
raise RuntimeError("WiFi connection timeout, Please check the SSID and password (only 2.4GHz networks are supported)")
|
||||
print('\nnetwork config:', wlan.ifconfig())
|
||||
return wlan
|
||||
|
||||
def image_base64(path="mixly.jpg"):
|
||||
from base64 import b64encode
|
||||
if isinstance(path, str):
|
||||
with open(path, 'rb') as f:
|
||||
_data = f.read()
|
||||
return 'data:image/{};base64,'.format(path.split('.')[-1]).encode() + b64encode(_data)
|
||||
else:
|
||||
return b'data:image/jpg;base64,' + b64encode(path)
|
||||
|
||||
def ntp(url='mixio.mixly.cn'):
|
||||
import urequests
|
||||
try:
|
||||
results=eval(urequests.get('http://{}/time.php'.format(url)).text)
|
||||
except Exception as e:
|
||||
raise RuntimeError("API request failed or WiFi is not connected",e)
|
||||
return results
|
||||
|
||||
def init_MQTT_client(address, username, password,MQTT_USR_PRJ):
|
||||
client = MQTTClient(hexlify(unique_id()), address, 1883, username, password)
|
||||
client.set_last_will(topic=MQTT_USR_PRJ+WILL_TOPIC, msg=client.client_id, qos=2)
|
||||
if client.connect()==0:
|
||||
client.publish(MQTT_USR_PRJ+ADDITIONAL_TOPIC, client.client_id, qos=0)
|
||||
time.sleep_ms(200)
|
||||
return client
|
||||
|
||||
# Add by Mixly Team
|
||||
def str_len(object):
|
||||
if isinstance(object, str):
|
||||
return len(object.encode('utf-8'))
|
||||
else:
|
||||
return len(object)
|
||||
#####################################################
|
||||
|
||||
class MQTTException(Exception):
|
||||
pass
|
||||
|
||||
class MQTTClient:
|
||||
def __init__(self, client_id, server, port=0, username=None, password=None, keepalive=60, ssl=False, ssl_params={}):
|
||||
if port == 0:
|
||||
port = 8883 if ssl else 1883
|
||||
self.client_id = client_id
|
||||
self.sock = None
|
||||
self.server = server
|
||||
self.addr = socket.getaddrinfo(server, port)[0][-1]
|
||||
self.ssl = ssl
|
||||
self.ssl_params = ssl_params
|
||||
self.pid = 0
|
||||
self._on_message = None
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.keepalive = keepalive
|
||||
self.lw_topic = None
|
||||
self.lw_msg = None
|
||||
self.lw_qos = 0
|
||||
self.lw_retain = False
|
||||
self._on_message_filtered = MQTTMatcher()
|
||||
self._star_time = time.ticks_ms()
|
||||
|
||||
def _send_str(self, s):
|
||||
self.sock.write(struct.pack("!H", str_len(s)))
|
||||
self.sock.write(s)
|
||||
|
||||
def _recv_len(self):
|
||||
n = 0
|
||||
sh = 0
|
||||
while 1:
|
||||
b = self.sock.read(1)[0]
|
||||
n |= (b & 0x7f) << sh
|
||||
if not b & 0x80:
|
||||
return n
|
||||
sh += 7
|
||||
|
||||
def set_callback(self, mqtt_topic, callback_method, MQTT_USR_PRJ):
|
||||
"""Registers a callback_method for a specific MQTT topic"""
|
||||
if mqtt_topic is None or callback_method is None:
|
||||
raise ValueError("MQTT topic and callback method must both be defined.")
|
||||
self._on_message_filtered[MQTT_USR_PRJ+mqtt_topic] = callback_method
|
||||
|
||||
def remove_callback(self, mqtt_topic):
|
||||
"""Removes a registered callback method"""
|
||||
if mqtt_topic is None:
|
||||
raise ValueError("MQTT Topic must be defined.")
|
||||
try:
|
||||
del self._on_message_filtered[mqtt_topic]
|
||||
except KeyError:
|
||||
raise KeyError(
|
||||
"MQTT topic callback not added with add_topic_callback."
|
||||
) from None
|
||||
|
||||
@property
|
||||
def on_message(self):
|
||||
"""Called when a new message has been received on a subscribed topic"""
|
||||
return self._on_message
|
||||
|
||||
@on_message.setter
|
||||
def on_message(self, method):
|
||||
self._on_message = method
|
||||
|
||||
def _handle_on_message(self, client, topic, message):
|
||||
matched = False
|
||||
if topic is not None:
|
||||
for callback in self._on_message_filtered.iter_match(topic):
|
||||
callback(client, topic.split("/")[-1], message) # on_msg with callback
|
||||
matched = True
|
||||
|
||||
if not matched and self.on_message: # regular on_message
|
||||
self.on_message(client, topic.split("/")[-1], message)
|
||||
|
||||
def set_last_will(self, topic, msg, retain=False, qos=0):
|
||||
assert 0 <= qos <= 2
|
||||
assert topic
|
||||
self.lw_topic = topic
|
||||
self.lw_msg = msg
|
||||
self.lw_qos = qos
|
||||
self.lw_retain = retain
|
||||
|
||||
def connect(self, clean_session=True):
|
||||
self.sock = socket.socket()
|
||||
self.sock.connect(self.addr)
|
||||
print(self.addr)
|
||||
if self.ssl:
|
||||
import ussl
|
||||
self.sock = ussl.wrap_socket(self.sock, **self.ssl_params)
|
||||
msg_header=bytearray([0x10])
|
||||
msg = bytearray(b"\x04MQTT\x04\x02\0\0")
|
||||
msg_length = 12 + str_len(self.client_id)
|
||||
msg[6] = clean_session << 1
|
||||
|
||||
if self.username is not None:
|
||||
msg_length += 2 + str_len(self.username) + 2 + str_len(self.password)
|
||||
msg[6] |= 0xC0
|
||||
if self.keepalive:
|
||||
assert self.keepalive < 65536
|
||||
msg[7] |= self.keepalive >> 8
|
||||
msg[8] |= self.keepalive & 0x00FF
|
||||
if self.lw_topic:
|
||||
msg_length += 2 + str_len(self.lw_topic) + 2 + str_len(self.lw_msg)
|
||||
msg[6] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3
|
||||
msg[6] |= self.lw_retain << 5
|
||||
|
||||
if msg_length > 0x7F:
|
||||
while msg_length>0:
|
||||
encoded_byte = msg_length % 0x80
|
||||
msg_length = msg_length // 0x80
|
||||
if msg_length > 0:
|
||||
encoded_byte |= 0x80
|
||||
msg_header.append(encoded_byte)
|
||||
msg_header.append(0x00)
|
||||
else:
|
||||
msg_header.append(msg_length)
|
||||
msg_header.append(0x00)
|
||||
|
||||
self.sock.write(msg_header)
|
||||
self.sock.write(msg)
|
||||
#print(hexlify(msg_header, ":"), hexlify(msg, ":"))
|
||||
self._send_str(self.client_id)
|
||||
if self.lw_topic:
|
||||
self._send_str(self.lw_topic)
|
||||
self._send_str(self.lw_msg)
|
||||
if self.username is not None:
|
||||
self._send_str(self.username)
|
||||
self._send_str(self.password)
|
||||
resp = self.sock.read(4)
|
||||
assert resp[0] == 0x20 and resp[1] == 0x02
|
||||
if resp[3] != 0:
|
||||
if resp[3] == 1:
|
||||
raise MQTTException("Unsupported Protocol")
|
||||
elif resp[3] == 2:
|
||||
raise MQTTException("Illegal ClientID")
|
||||
elif resp[3] == 3:
|
||||
raise MQTTException("Server Unavailable")
|
||||
elif resp[3] == 4:
|
||||
raise MQTTException("Invalid username and password format")
|
||||
elif resp[3] == 5:
|
||||
raise MQTTException("Unauthorized")
|
||||
else:
|
||||
raise MQTTException(resp[3])
|
||||
return resp[2] & 1
|
||||
|
||||
|
||||
def disconnect(self,MQTT_USR_PRJ):
|
||||
#MQTT_USR_PRJ = "{}/{}/".format(self.username,self.project)
|
||||
self.publish(MQTT_USR_PRJ+WILL_TOPIC, self.client_id, qos=1)
|
||||
self.sock.write(b"\xe0\0")
|
||||
self.sock.close()
|
||||
|
||||
def ping(self):
|
||||
self.sock.write(b"\xc0\0")
|
||||
|
||||
def pingSync(self):
|
||||
self.ping()
|
||||
for i in range(0,10):
|
||||
msg = self.check_msg()
|
||||
if msg == "PINGRESP":
|
||||
return True
|
||||
time.sleep_ms(100)
|
||||
return False
|
||||
|
||||
def publish(self, topic, msg, retain=False, qos=0):
|
||||
# msg = pubData(msg)
|
||||
if "+" in topic or "#" in topic:
|
||||
raise MQTTException("Publish topic can not contain wildcards.")
|
||||
# check msg/qos kwargs
|
||||
if msg is None:
|
||||
raise MQTTException("Message can not be None.")
|
||||
if isinstance(msg, (int, float)):
|
||||
msg = str(msg).encode("ascii")
|
||||
elif isinstance(msg, str):
|
||||
msg = str(msg).encode("utf-8")
|
||||
elif isinstance(msg, bytes):
|
||||
pass
|
||||
else:
|
||||
raise MQTTException("Invalid message data type.")
|
||||
pkt = bytearray(b"\x30\0\0\0")
|
||||
pkt[0] |= qos << 1 | retain
|
||||
sz = 2 + str_len(topic) + str_len(msg)
|
||||
if qos > 0:
|
||||
sz += 2
|
||||
assert sz < 2097152
|
||||
i = 1
|
||||
while sz > 0x7f:
|
||||
pkt[i] = (sz & 0x7f) | 0x80
|
||||
sz >>= 7
|
||||
i += 1
|
||||
pkt[i] = sz
|
||||
#print(hex(str_len(pkt)), hexlify(pkt, ":"))
|
||||
self.sock.settimeout(0.05)
|
||||
#self.sock.setblocking(True)
|
||||
self.sock.write(pkt, i + 1)
|
||||
self._send_str(topic)
|
||||
if qos > 0:
|
||||
self.pid += 1
|
||||
pid = self.pid
|
||||
struct.pack_into("!H", pkt, 0, pid)
|
||||
self.sock.write(pkt, 2)
|
||||
self.sock.write(msg)
|
||||
if qos == 1:
|
||||
while 1:
|
||||
op = self.wait_msg()
|
||||
if op == 0x40:
|
||||
sz = self.sock.read(1)
|
||||
assert sz == b"\x02"
|
||||
rcv_pid = self.sock.read(2)
|
||||
rcv_pid = rcv_pid[0] << 8 | rcv_pid[1]
|
||||
if pid == rcv_pid:
|
||||
return
|
||||
elif qos == 2:
|
||||
assert 0
|
||||
|
||||
def subscribe(self, topic, qos=0):
|
||||
#assert self.cb is not None, "Subscribe callback is not set"
|
||||
pkt = bytearray(b"\x82\0\0\0")
|
||||
self.pid += 1
|
||||
if isinstance(topic, str):
|
||||
topic=topic.encode()
|
||||
struct.pack_into("!BH", pkt, 1, 2 + 2 + str_len(topic) + 1, self.pid)
|
||||
#print(hex(str_len(pkt)), hexlify(pkt, ":"))
|
||||
self.sock.write(pkt)
|
||||
self._send_str(topic)
|
||||
self.sock.write(qos.to_bytes(1, "little"))
|
||||
while 1:
|
||||
op = self.wait_msg()
|
||||
if op == 0x90:
|
||||
resp = self.sock.read(4)
|
||||
#print(resp)
|
||||
assert resp[1] == pkt[2] and resp[2] == pkt[3]
|
||||
if resp[3] == 0x80:
|
||||
raise MQTTException(resp[3])
|
||||
return
|
||||
|
||||
# Wait for a single incoming MQTT message and process it.
|
||||
def wait_msg(self):
|
||||
res = self.sock.read(1)
|
||||
time.sleep_ms(50)
|
||||
self.sock.settimeout(0.05)
|
||||
#self.sock.setblocking(True)
|
||||
if res is None:
|
||||
return None
|
||||
if res == b"":
|
||||
raise OSError(-1)
|
||||
if res == b"\xd0": # PINGRESP
|
||||
sz = self.sock.read(1)[0]
|
||||
assert sz == 0
|
||||
return "PINGRESP"
|
||||
op = res[0]
|
||||
if op & 0xf0 != 0x30:
|
||||
return op
|
||||
sz = self._recv_len()
|
||||
topic_len = self.sock.read(2)
|
||||
topic_len = (topic_len[0] << 8) | topic_len[1]
|
||||
topic = self.sock.read(topic_len)
|
||||
sz -= topic_len + 2
|
||||
if op & 6:
|
||||
pid = self.sock.read(2)
|
||||
pid = pid[0] << 8 | pid[1]
|
||||
sz -= 2
|
||||
msg = self.sock.read(sz)
|
||||
self._handle_on_message(self, str(topic, "utf-8"), str(msg, "utf-8"))
|
||||
if op & 6 == 2:
|
||||
pkt = bytearray(b"\x40\x02\0\0")
|
||||
struct.pack_into("!H", pkt, 2, pid)
|
||||
self.sock.write(pkt)
|
||||
elif op & 6 == 4:
|
||||
assert 0
|
||||
|
||||
# Checks whether a pending message from server is available.
|
||||
def check_msg(self):
|
||||
self.sock.settimeout(0.05)
|
||||
if time.ticks_diff(time.ticks_ms(), self._star_time) >60000:
|
||||
self._star_time = time.ticks_ms()
|
||||
self.ping()
|
||||
return self.wait_msg()
|
||||
|
||||
def get_server_info(self):
|
||||
return (self.server, self.username, self.password)
|
||||
94
mixly/boards/default/micropython/build/lib/mixpy.py
Normal file
94
mixly/boards/default/micropython/build/lib/mixpy.py
Normal file
@@ -0,0 +1,94 @@
|
||||
#coding=utf-8
|
||||
import math
|
||||
|
||||
def math_map(v, al, ah, bl, bh):
|
||||
if al==ah:
|
||||
return bl
|
||||
if al < ah:
|
||||
v = max(min(ah,v),al)
|
||||
if al > ah:
|
||||
v = max(min(al,v),ah)
|
||||
return bl + (bh - bl) * (v - al) / (ah - al)
|
||||
|
||||
def math_mean(myList):
|
||||
localList = [e for e in myList if type(e) == int or type(e) == float]
|
||||
if not localList: return
|
||||
return float(sum(localList)) / len(localList)
|
||||
|
||||
def math_median(myList):
|
||||
localList = sorted([e for e in myList if type(e) == int or type(e) == float])
|
||||
if not localList: return
|
||||
if len(localList) % 2 == 0:
|
||||
return (localList[len(localList) // 2 - 1] + localList[len(localList) // 2]) / 2.0
|
||||
else:
|
||||
return localList[(len(localList) - 1) // 2]
|
||||
|
||||
def math_modes(some_list):
|
||||
modes = []
|
||||
# Using a lists of [item, count] to keep count rather than dict
|
||||
# to avoid "unhashable" errors when the counted item is itself a list or dict.
|
||||
counts = []
|
||||
maxCount = 1
|
||||
for item in some_list:
|
||||
found = False
|
||||
for count in counts:
|
||||
if count[0] == item:
|
||||
count[1] += 1
|
||||
maxCount = max(maxCount, count[1])
|
||||
found = True
|
||||
if not found:
|
||||
counts.append([item, 1])
|
||||
for counted_item, item_count in counts:
|
||||
if item_count == maxCount:
|
||||
modes.append(counted_item)
|
||||
return modes
|
||||
|
||||
def math_standard_deviation(numbers):
|
||||
n = len(numbers)
|
||||
if n == 0: return
|
||||
mean = float(sum(numbers)) / n
|
||||
variance = sum((x - mean) ** 2 for x in numbers) / n
|
||||
return math.sqrt(variance)
|
||||
|
||||
def lists_sort(my_list, type, reverse):
|
||||
def try_float(s):
|
||||
try:
|
||||
return float(s)
|
||||
except:
|
||||
return 0
|
||||
key_funcs = {
|
||||
"NUMERIC": try_float,
|
||||
"TEXT": str,
|
||||
"IGNORE_CASE": lambda s: str(s).lower()
|
||||
}
|
||||
key_func = key_funcs[type]
|
||||
list_cpy = list(my_list)
|
||||
return sorted(list_cpy, key=key_func, reverse=reverse)
|
||||
|
||||
def format_content(mydict, cid):
|
||||
if 'lat' in mydict and 'long' in mydict:
|
||||
res = '{'+'"lat": "{}", "long": "{}", "clientid": "{}"'.format(mydict.pop('lat'),mydict.pop('long'),cid)
|
||||
if len(mydict)>0:
|
||||
res += ', "message": ['
|
||||
for d in mydict:
|
||||
res += '{{"label": "{}", "value": "{}"}},'.format(d,mydict[d])
|
||||
res = res[:-1] + "]"
|
||||
res += '}'
|
||||
return res
|
||||
else:
|
||||
print('Invalid Input')
|
||||
|
||||
def format_str(d):
|
||||
return str(d).replace("'",'"')
|
||||
|
||||
|
||||
def analyse_sharekey(url):
|
||||
import urequests
|
||||
import json
|
||||
response = urequests.get(url)
|
||||
|
||||
if response.text == '-1':
|
||||
raise AttributeError('Invalid share key')
|
||||
else:
|
||||
result = json.loads(response.text)
|
||||
return (result['0'], result['1'], result['2'])
|
||||
74
mixly/boards/default/micropython/build/lib/mk_pb4023.py
Normal file
74
mixly/boards/default/micropython/build/lib/mk_pb4023.py
Normal file
@@ -0,0 +1,74 @@
|
||||
"""
|
||||
MK-PB4023PS&ASL&VC-A01E
|
||||
|
||||
MicroPython library for the MK-PB4023PS&ASL&VC-A01E (PS,ASL,CS)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
_MK_SYSM = const(0x80)
|
||||
_MK_ID = const(0x98)
|
||||
_MK_DATA = const(0xA0)
|
||||
|
||||
class MK_PB4023:
|
||||
def __init__(self, i2c_bus, addr=0x39):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
if self._rreg(_MK_ID) != 0xA0:
|
||||
raise AttributeError("Cannot find a MK-PB4023")
|
||||
self._configure()
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)
|
||||
|
||||
def _configure(self):
|
||||
'''Configuration Register'''
|
||||
self._wreg(0X82, 0x80)
|
||||
self._wreg(0x83, 0x01)
|
||||
self._wreg(0x84, 0x07)
|
||||
self._wreg(0x85, 0x0B)
|
||||
self._wreg(0x86, 0x03)
|
||||
self._wreg(0x87, 0x1A)
|
||||
self._wreg(0x89, 0x38)
|
||||
self._wreg(_MK_SYSM,0x0F) #Enable Register
|
||||
|
||||
def getdata(self):
|
||||
'''Processing data acquisition'''
|
||||
_buf = self._rreg(_MK_DATA, 12)
|
||||
_r = _buf[0] | _buf[1] << 8
|
||||
_g = _buf[2] | _buf[3] << 8
|
||||
_b = _buf[4] | _buf[5] << 8
|
||||
_c = _buf[6] | _buf[7] << 8
|
||||
_ir = _buf[8] | _buf[9] << 8
|
||||
_ps = _buf[10] | _buf[11] << 8
|
||||
return _c, _ir, (_r, _g, _b), _ps
|
||||
|
||||
def color(self):
|
||||
w, _, (r, g, b), _ = self.getdata()
|
||||
if w == 0:
|
||||
return (0, 0, 0)
|
||||
else:
|
||||
red = int(pow((int((r / w) * 256) / 255), 2.5) * 255)
|
||||
green = int(pow((int((g / w) * 256) / 255), 2.5) * 255)
|
||||
blue = int(pow((int((b / w) * 256) / 255), 2.5) * 255)
|
||||
return (min(red, 255), min(green, 255), min(blue, 255))
|
||||
|
||||
def color_raw(self):
|
||||
return self.getdata()[2]
|
||||
|
||||
def ir(self):
|
||||
return self.getdata()[1]
|
||||
|
||||
def als(self):
|
||||
w, ir, (r, g, b), _ = self.getdata()
|
||||
return round((w + ir + r + g + b) / 17.8, 2)
|
||||
|
||||
def ps(self):
|
||||
return self.getdata()[3]
|
||||
149
mixly/boards/default/micropython/build/lib/mmc5603.py
Normal file
149
mixly/boards/default/micropython/build/lib/mmc5603.py
Normal file
@@ -0,0 +1,149 @@
|
||||
"""
|
||||
MMC5603
|
||||
|
||||
Micropython library for the MMC5603NJ(Magnetic)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20221017
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time,math
|
||||
from micropython import const
|
||||
|
||||
MMC5603_ADDRESS = const(0x30)
|
||||
|
||||
MMC5603_REG_DATA = const(0x00)
|
||||
MMC5603_REG_TMP = const(0x09)
|
||||
MMC5603_REG_ODR = const(0x1A)
|
||||
MMC5603_REG_CTRL0 = const(0x1B)
|
||||
MMC5603_REG_CTRL1 = const(0x1C)
|
||||
MMC5603_REG_CTRL2 = const(0x1D)
|
||||
|
||||
MMC5603_REG_X_THD = const(0x1E)
|
||||
MMC5603_REG_Y_THD = const(0x1F)
|
||||
MMC5603_REG_Z_THD = const(0x20)
|
||||
MMC5603_REG_ST_X_VAL = const(0x27)
|
||||
MMC5603_REG_DEVICE_ID = const(0x39)
|
||||
|
||||
class MMC5603:
|
||||
def __init__(self, i2c_bus):
|
||||
self._device = i2c_bus
|
||||
self._address = MMC5603_ADDRESS
|
||||
self.raw_x = 0.0
|
||||
self.raw_y = 0.0
|
||||
self.raw_z = 0.0
|
||||
|
||||
if self._chip_id() != 0x10: #Check product ID
|
||||
raise AttributeError("Cannot find a MMC5603")
|
||||
try: #Read calibration file
|
||||
import magnetic_cal
|
||||
self._offset_x = magnetic_cal._offset_x
|
||||
self._offset_y = magnetic_cal._offset_y
|
||||
self._offset_z = magnetic_cal._offset_z
|
||||
except:
|
||||
self._offset_x = 524288
|
||||
self._offset_y = 524288
|
||||
self._offset_z = 524288
|
||||
#print("offset:",self._offset_x ,self._offset_y,self._offset_z)
|
||||
|
||||
self._auto_selftest() #Auto self-test registers configuration
|
||||
self._set()
|
||||
self._continuous_mode(0x00, 50) #Work mode setting
|
||||
time.sleep(0.05)
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg,nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _chip_id(self):
|
||||
return self._rreg(MMC5603_REG_DEVICE_ID)
|
||||
|
||||
def _auto_selftest(self):
|
||||
'''Auto self-test registers configuration'''
|
||||
st_thd_reg=[0,0,0]
|
||||
st_thr_data=[0,0,0]
|
||||
#/* Read trim data from reg 0x27-0x29 */
|
||||
_buffer=self._rreg(MMC5603_REG_ST_X_VAL,3)
|
||||
for i in range(0, 3, 1):
|
||||
st_thr_data[i]=(_buffer[i]-128)*32
|
||||
if st_thr_data[i] < 0:
|
||||
st_thr_data[i]=-st_thr_data[i]
|
||||
st_thd=(st_thr_data[i]-st_thr_data[i]//5)//8
|
||||
if st_thd > 255:
|
||||
st_thd_reg[i]=0xFF
|
||||
else:
|
||||
st_thd_reg[i]=st_thd
|
||||
#/* Write threshold into the reg 0x1E-0x20 */
|
||||
self._wreg(MMC5603_REG_X_THD, st_thd_reg[0])
|
||||
self._wreg(MMC5603_REG_Y_THD, st_thd_reg[1])
|
||||
self._wreg(MMC5603_REG_Z_THD, st_thd_reg[2])
|
||||
|
||||
def _set(self):
|
||||
'''Do SET operation'''
|
||||
self._wreg(MMC5603_REG_CTRL0, 0X08)
|
||||
time.sleep(0.005)
|
||||
|
||||
def _continuous_mode(self,bandwith,sampling_rate):
|
||||
'''Work mode setting'''
|
||||
self._wreg(MMC5603_REG_CTRL1, bandwith)
|
||||
self._wreg(MMC5603_REG_ODR, sampling_rate)
|
||||
self._wreg(MMC5603_REG_CTRL0, 0X80|0X20)
|
||||
self._wreg(MMC5603_REG_CTRL2, 0x10)
|
||||
|
||||
def getdata(self):
|
||||
_buf=self._rreg( MMC5603_REG_DATA,9)
|
||||
#/* Transform to unit Gauss */
|
||||
self.raw_x=(_buf[0] << 12) | (_buf[1] << 4) | (_buf[6] >> 4)
|
||||
self.raw_y=(_buf[2] << 12) | (_buf[3] << 4) | (_buf[7] >> 4)
|
||||
self.raw_z=(_buf[4] << 12) | (_buf[5] << 4) | (_buf[8] >> 4)
|
||||
return (-0.0625*(self.raw_x-self._offset_x), -0.0625*(self.raw_y-self._offset_y), -0.0625*(self.raw_z-self._offset_z))
|
||||
|
||||
def calibrate(self):
|
||||
print("The magnetic field will be calibrated")
|
||||
print("Please pick up the board and rotate the '8' shape in the air")
|
||||
time.sleep(2)
|
||||
self.getdata()
|
||||
min_x = max_x = self.raw_x
|
||||
min_y = max_y = self.raw_y
|
||||
min_z = max_z = self.raw_z
|
||||
ticks_start = time.ticks_ms()
|
||||
while (time.ticks_diff(time.ticks_ms(), ticks_start) < 20000) :
|
||||
self.getdata()
|
||||
min_x = min(self.raw_x, min_x)
|
||||
max_x = max(self.raw_x, max_x)
|
||||
min_y = min(self.raw_y, min_y)
|
||||
max_y = max(self.raw_y, max_y)
|
||||
min_z = min(self.raw_z, min_z)
|
||||
max_z = max(self.raw_z, max_z)
|
||||
time.sleep_ms(20)
|
||||
if time.ticks_diff(time.ticks_ms(), ticks_start) % 20 ==0:
|
||||
print("=",end ="")
|
||||
print(" 100%")
|
||||
self._offset_x = (max_x + min_x) / 2
|
||||
self._offset_y = (max_y + min_y) / 2
|
||||
self._offset_z = (max_z + min_z) / 2
|
||||
print("Save x_offset:{}, y_offset:{}, z_offset:{}".format(self._offset_x,self._offset_y,self._offset_z))
|
||||
s_f = open("magnetic_cal.py", "w+")
|
||||
s_f.write("_offset_x="+str(self._offset_x)+"\n")
|
||||
s_f.write("_offset_y="+str(self._offset_y)+"\n")
|
||||
s_f.write("_offset_z="+str(self._offset_z)+"\n")
|
||||
s_f.close()
|
||||
time.sleep(2)
|
||||
|
||||
def getstrength(self):
|
||||
_x,_y,_z=self.getdata()
|
||||
return (math.sqrt(math.pow(_x, 2) + pow(_y, 2) + pow(_z, 2)))
|
||||
|
||||
def getangle(self,upright=False):
|
||||
_x,_y,_z=self.getdata()
|
||||
if upright: #vertical
|
||||
angle=math.atan2(_z, -_x)*(180 / math.pi) + 180 + 3
|
||||
return angle if angle<360 else angle-360
|
||||
else: #horizontal
|
||||
angle=math.atan2(_y, -_x)*(180 / math.pi) + 180 + 3
|
||||
return angle if angle<360 else angle-360
|
||||
585
mixly/boards/default/micropython/build/lib/mpu9250.py
Normal file
585
mixly/boards/default/micropython/build/lib/mpu9250.py
Normal file
@@ -0,0 +1,585 @@
|
||||
"""
|
||||
MicroPython I2C driver for MPU9250 9-axis motion tracking device
|
||||
"""
|
||||
from micropython import const
|
||||
import ustruct
|
||||
import time
|
||||
import math
|
||||
from machine import Pin,SoftI2C
|
||||
|
||||
_GYRO_CONFIG = const(0x1b)
|
||||
_ACCEL_CONFIG = const(0x1c)
|
||||
_ACCEL_CONFIG2 = const(0x1d)
|
||||
_INT_PIN_CFG = const(0x37)
|
||||
_ACCEL_XOUT_H = const(0x3b)
|
||||
_ACCEL_XOUT_L = const(0x3c)
|
||||
_ACCEL_YOUT_H = const(0x3d)
|
||||
_ACCEL_YOUT_L = const(0x3e)
|
||||
_ACCEL_ZOUT_H = const(0x3f)
|
||||
_ACCEL_ZOUT_L= const(0x40)
|
||||
_TEMP_OUT_H = const(0x41)
|
||||
_TEMP_OUT_L = const(0x42)
|
||||
_GYRO_XOUT_H = const(0x43)
|
||||
_GYRO_XOUT_L = const(0x44)
|
||||
_GYRO_YOUT_H = const(0x45)
|
||||
_GYRO_YOUT_L = const(0x46)
|
||||
_GYRO_ZOUT_H = const(0x47)
|
||||
_GYRO_ZOUT_L = const(0x48)
|
||||
_WHO_AM_I = const(0x75)
|
||||
|
||||
#_ACCEL_FS_MASK = const(0b00011000)
|
||||
ACCEL_FS_SEL_2G = const(0b00000000)
|
||||
ACCEL_FS_SEL_4G = const(0b00001000)
|
||||
ACCEL_FS_SEL_8G = const(0b00010000)
|
||||
ACCEL_FS_SEL_16G = const(0b00011000)
|
||||
|
||||
_ACCEL_SO_2G = 16384 # 1 / 16384 ie. 0.061 mg / digit
|
||||
_ACCEL_SO_4G = 8192 # 1 / 8192 ie. 0.122 mg / digit
|
||||
_ACCEL_SO_8G = 4096 # 1 / 4096 ie. 0.244 mg / digit
|
||||
_ACCEL_SO_16G = 2048 # 1 / 2048 ie. 0.488 mg / digit
|
||||
|
||||
#_GYRO_FS_MASK = const(0b00011000)
|
||||
GYRO_FS_SEL_250DPS = const(0b00000000)
|
||||
GYRO_FS_SEL_500DPS = const(0b00001000)
|
||||
GYRO_FS_SEL_1000DPS = const(0b00010000)
|
||||
GYRO_FS_SEL_2000DPS = const(0b00011000)
|
||||
|
||||
_GYRO_SO_250DPS = 131
|
||||
_GYRO_SO_500DPS = 62.5
|
||||
_GYRO_SO_1000DPS = 32.8
|
||||
_GYRO_SO_2000DPS = 16.4
|
||||
|
||||
# Used for enablind and disabling the i2c bypass access
|
||||
_I2C_BYPASS_MASK = const(0b00000010)
|
||||
_I2C_BYPASS_EN = const(0b00000010)
|
||||
_I2C_BYPASS_DIS = const(0b00000000)
|
||||
|
||||
SF_G = 1
|
||||
SF_M_S2 = 9.80665 # 1 g = 9.80665 m/s2 ie. standard gravity
|
||||
SF_DEG_S = 1
|
||||
SF_RAD_S = 57.295779578552 # 1 rad/s is 57.295779578552 deg/s
|
||||
|
||||
|
||||
_WIA = const(0x00)
|
||||
_HXL = const(0x03)
|
||||
_HXH = const(0x04)
|
||||
_HYL = const(0x05)
|
||||
_HYH = const(0x06)
|
||||
_HZL = const(0x07)
|
||||
_HZH = const(0x08)
|
||||
_ST2 = const(0x09)
|
||||
_CNTL1 = const(0x0a)
|
||||
_ASAX = const(0x10)
|
||||
_ASAY = const(0x11)
|
||||
_ASAZ = const(0x12)
|
||||
|
||||
_MODE_POWER_DOWN = 0b00000000
|
||||
MODE_SINGLE_MEASURE = 0b00000001
|
||||
MODE_CONTINOUS_MEASURE_1 = 0b00000010 # 8Hz
|
||||
MODE_CONTINOUS_MEASURE_2 = 0b00000110 # 100Hz
|
||||
MODE_EXTERNAL_TRIGGER_MEASURE = 0b00000100
|
||||
_MODE_SELF_TEST = 0b00001000
|
||||
_MODE_FUSE_ROM_ACCESS = 0b00001111
|
||||
|
||||
OUTPUT_14_BIT = 0b00000000
|
||||
OUTPUT_16_BIT = 0b00010000
|
||||
|
||||
_SO_14BIT = 0.6 # per digit when 14bit mode
|
||||
_SO_16BIT = 0.15 # per digit when 16bit mode
|
||||
|
||||
class MPU6500:
|
||||
"""Class which provides interface to MPU6500 6-axis motion tracking device."""
|
||||
def __init__(
|
||||
self, i2c, address=0x68,
|
||||
accel_fs=ACCEL_FS_SEL_2G, gyro_fs=GYRO_FS_SEL_250DPS,
|
||||
accel_sf=SF_M_S2, gyro_sf=SF_RAD_S
|
||||
):
|
||||
self.i2c = i2c
|
||||
self.address = address
|
||||
|
||||
if 0x71 != self.whoami:
|
||||
raise RuntimeError("MPU9250 not found in I2C bus.")
|
||||
|
||||
self._accel_so = self._accel_fs(accel_fs)
|
||||
self._gyro_so = self._gyro_fs(gyro_fs)
|
||||
self._accel_sf = accel_sf
|
||||
self._gyro_sf = gyro_sf
|
||||
|
||||
# Enable I2C bypass to access for MPU9250 magnetometer access.
|
||||
char = self._register_char(_INT_PIN_CFG)
|
||||
char &= ~_I2C_BYPASS_MASK # clear I2C bits
|
||||
char |= _I2C_BYPASS_EN
|
||||
self._register_char(_INT_PIN_CFG, char)
|
||||
|
||||
@property
|
||||
def temperature(self):
|
||||
tempbuf=self._register_short(0x41)
|
||||
return tempbuf/333.87 + 21 # I think
|
||||
|
||||
# @property
|
||||
def acceleration(self):
|
||||
so = self._accel_so
|
||||
sf = self._accel_sf
|
||||
|
||||
xyz = self._register_three_shorts(_ACCEL_XOUT_H)
|
||||
return tuple([value / so * sf for value in xyz])
|
||||
|
||||
@property
|
||||
def gyro(self):
|
||||
""" X, Y, Z radians per second as floats."""
|
||||
so = self._gyro_so
|
||||
sf = self._gyro_sf
|
||||
|
||||
xyz = self._register_three_shorts(_GYRO_XOUT_H)
|
||||
return tuple([value / so * sf for value in xyz])
|
||||
|
||||
@property
|
||||
def whoami(self):
|
||||
""" Value of the whoami register. """
|
||||
return self._register_char(_WHO_AM_I)
|
||||
|
||||
def _register_short(self, register, value=None, buf=bytearray(2)):
|
||||
if value is None:
|
||||
self.i2c.readfrom_mem_into(self.address, register, buf)
|
||||
return ustruct.unpack(">h", buf)[0]
|
||||
|
||||
ustruct.pack_into(">h", buf, 0, value)
|
||||
return self.i2c.writeto_mem(self.address, register, buf)
|
||||
|
||||
def _register_three_shorts(self, register, buf=bytearray(6)):
|
||||
self.i2c.readfrom_mem_into(self.address, register, buf)
|
||||
return ustruct.unpack(">hhh", buf)
|
||||
|
||||
def _register_char(self, register, value=None, buf=bytearray(1)):
|
||||
if value is None:
|
||||
self.i2c.readfrom_mem_into(self.address, register, buf)
|
||||
return buf[0]
|
||||
|
||||
ustruct.pack_into("<b", buf, 0, value)
|
||||
return self.i2c.writeto_mem(self.address, register, buf)
|
||||
|
||||
def _accel_fs(self, value):
|
||||
self._register_char(_ACCEL_CONFIG, value)
|
||||
|
||||
# Return the sensitivity divider
|
||||
if ACCEL_FS_SEL_2G == value:
|
||||
return _ACCEL_SO_2G
|
||||
elif ACCEL_FS_SEL_4G == value:
|
||||
return _ACCEL_SO_4G
|
||||
elif ACCEL_FS_SEL_8G == value:
|
||||
return _ACCEL_SO_8G
|
||||
elif ACCEL_FS_SEL_16G == value:
|
||||
return _ACCEL_SO_16G
|
||||
|
||||
def _gyro_fs(self, value):
|
||||
self._register_char(_GYRO_CONFIG, value)
|
||||
|
||||
# Return the sensitivity divider
|
||||
if GYRO_FS_SEL_250DPS == value:
|
||||
return _GYRO_SO_250DPS
|
||||
elif GYRO_FS_SEL_500DPS == value:
|
||||
return _GYRO_SO_500DPS
|
||||
elif GYRO_FS_SEL_1000DPS == value:
|
||||
return _GYRO_SO_1000DPS
|
||||
elif GYRO_FS_SEL_2000DPS == value:
|
||||
return _GYRO_SO_2000DPS
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exception_type, exception_value, traceback):
|
||||
pass
|
||||
|
||||
class AK8963:
|
||||
"""Class which provides interface to AK8963 magnetometer."""
|
||||
def __init__(
|
||||
self, i2c, address=0x0c,
|
||||
mode=MODE_CONTINOUS_MEASURE_1, output=OUTPUT_16_BIT,
|
||||
offset=(0, 0, 0), scale=(1, 1, 1)
|
||||
):
|
||||
self.i2c = i2c
|
||||
self.address = address
|
||||
self._offset = offset
|
||||
self._scale = scale
|
||||
|
||||
if 0x48 != self.whoami:
|
||||
raise RuntimeError("MPU9250 not found in I2C bus.")
|
||||
|
||||
# Sensitivity adjustement values
|
||||
self._register_char(_CNTL1, _MODE_FUSE_ROM_ACCESS)
|
||||
asax = self._register_char(_ASAX)
|
||||
asay = self._register_char(_ASAY)
|
||||
asaz = self._register_char(_ASAZ)
|
||||
self._register_char(_CNTL1, _MODE_POWER_DOWN)
|
||||
|
||||
# Should wait atleast 100us before next mode
|
||||
self._adjustement = (
|
||||
(0.5 * (asax - 128)) / 128 + 1,
|
||||
(0.5 * (asay - 128)) / 128 + 1,
|
||||
(0.5 * (asaz - 128)) / 128 + 1
|
||||
)
|
||||
|
||||
# Power on
|
||||
self._register_char(_CNTL1, (mode | output))
|
||||
|
||||
if output is OUTPUT_16_BIT:
|
||||
self._so = _SO_16BIT
|
||||
else:
|
||||
self._so = _SO_14BIT
|
||||
|
||||
|
||||
@property
|
||||
def magnetic(self):
|
||||
"""
|
||||
X, Y, Z axis micro-Tesla (uT) as floats.
|
||||
"""
|
||||
xyz = list(self._register_three_shorts(_HXL))
|
||||
self._register_char(_ST2) # Enable updating readings again
|
||||
|
||||
# Apply factory axial sensitivy adjustements
|
||||
xyz[0] *= self._adjustement[0]
|
||||
xyz[1] *= self._adjustement[1]
|
||||
xyz[2] *= self._adjustement[2]
|
||||
|
||||
# Apply output scale determined in constructor
|
||||
so = self._so
|
||||
xyz[0] *= so
|
||||
xyz[1] *= so
|
||||
xyz[2] *= so
|
||||
|
||||
# Apply hard iron ie. offset bias from calibration
|
||||
xyz[0] -= self._offset[0]
|
||||
xyz[1] -= self._offset[1]
|
||||
xyz[2] -= self._offset[2]
|
||||
|
||||
# Apply soft iron ie. scale bias from calibration
|
||||
xyz[0] *= self._scale[0]
|
||||
xyz[1] *= self._scale[1]
|
||||
xyz[2] *= self._scale[2]
|
||||
|
||||
return tuple(xyz)
|
||||
|
||||
@property
|
||||
def adjustement(self):
|
||||
return self._adjustement
|
||||
|
||||
@property
|
||||
def whoami(self):
|
||||
""" Value of the whoami register. """
|
||||
return self._register_char(_WIA)
|
||||
|
||||
def calibrate(self, count=3, delay=200):
|
||||
self._offset = (0, 0, 0)
|
||||
self._scale = (1, 1, 1)
|
||||
|
||||
reading = self.magnetic
|
||||
minx = maxx = reading[0]
|
||||
miny = maxy = reading[1]
|
||||
minz = maxz = reading[2]
|
||||
|
||||
while count:
|
||||
time.sleep_ms(delay)
|
||||
reading = self.magnetic
|
||||
minx = min(minx, reading[0])
|
||||
maxx = max(maxx, reading[0])
|
||||
miny = min(miny, reading[1])
|
||||
maxy = max(maxy, reading[1])
|
||||
minz = min(minz, reading[2])
|
||||
maxz = max(maxz, reading[2])
|
||||
count -= 1
|
||||
|
||||
|
||||
# Hard iron correction
|
||||
offset_x = (maxx + minx) / 2
|
||||
offset_y = (maxy + miny) / 2
|
||||
offset_z = (maxz + minz) / 2
|
||||
|
||||
self._offset = (offset_x, offset_y, offset_z)
|
||||
|
||||
# Soft iron correction
|
||||
avg_delta_x = (maxx - minx) / 2
|
||||
avg_delta_y = (maxy - miny) / 2
|
||||
avg_delta_z = (maxz - minz) / 2
|
||||
|
||||
avg_delta = (avg_delta_x + avg_delta_y + avg_delta_z) / 3
|
||||
|
||||
scale_x = avg_delta / avg_delta_x
|
||||
scale_y = avg_delta / avg_delta_y
|
||||
scale_z = avg_delta / avg_delta_z
|
||||
|
||||
self._scale = (scale_x, scale_y, scale_z)
|
||||
|
||||
return self._offset, self._scale
|
||||
|
||||
def _register_short(self, register, value=None, buf=bytearray(2)):
|
||||
if value is None:
|
||||
self.i2c.readfrom_mem_into(self.address, register, buf)
|
||||
return ustruct.unpack("<h", buf)[0]
|
||||
|
||||
ustruct.pack_into("<h", buf, 0, value)
|
||||
return self.i2c.writeto_mem(self.address, register, buf)
|
||||
|
||||
def _register_three_shorts(self, register, buf=bytearray(6)):
|
||||
self.i2c.readfrom_mem_into(self.address, register, buf)
|
||||
return ustruct.unpack("<hhh", buf)
|
||||
|
||||
def _register_char(self, register, value=None, buf=bytearray(1)):
|
||||
if value is None:
|
||||
self.i2c.readfrom_mem_into(self.address, register, buf)
|
||||
return buf[0]
|
||||
|
||||
ustruct.pack_into("<b", buf, 0, value)
|
||||
return self.i2c.writeto_mem(self.address, register, buf)
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exception_type, exception_value, traceback):
|
||||
pass
|
||||
|
||||
|
||||
class MPU9250:
|
||||
"""Class which provides interface to MPU9250 9-axis motion tracking device."""
|
||||
def __init__(self, i2c, mpu6500 = None, ak8963 = None):
|
||||
if mpu6500 is None:
|
||||
self.mpu6500 = MPU6500(i2c)
|
||||
else:
|
||||
self.mpu6500 = mpu6500
|
||||
|
||||
if ak8963 is None:
|
||||
self.ak8963 = AK8963(i2c)
|
||||
else:
|
||||
self.ak8963 = ak8963
|
||||
|
||||
def mpu9250_get_temperature(self):
|
||||
return self.mpu6500.temperature
|
||||
|
||||
def mpu9250_get_values(self):
|
||||
g = self.mpu6500.acceleration()
|
||||
a = [round(x/9.8, 2) for x in g]
|
||||
return tuple(a)
|
||||
|
||||
def mpu9250_get_x(self):
|
||||
return round(self.mpu6500.acceleration()[0]/9.8, 2)
|
||||
|
||||
def mpu9250_get_y(self):
|
||||
return round(self.mpu6500.acceleration()[1]/9.8, 2)
|
||||
|
||||
def mpu9250_get_z(self):
|
||||
return round(self.mpu6500.acceleration()[2]/9.8, 2)
|
||||
|
||||
|
||||
def mpu9250_is_gesture(self,choice):
|
||||
if choice == 'face up':
|
||||
if self.mpu6500.acceleration()[2] <= -9:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if choice == 'face down':
|
||||
if self.mpu6500.acceleration()[2] >= 9:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if choice == 'shake':
|
||||
if abs(self.mpu6500.acceleration()[0]) >= 9 and abs(self.mpu6500.acceleration()[1]) >= 9 :
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if choice == 'up':
|
||||
if self.mpu6500.acceleration()[1] >= 9:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if choice == 'down':
|
||||
if self.mpu6500.acceleration()[1] <= -9:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if choice == 'right':
|
||||
if self.mpu6500.acceleration()[0] <= -9:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if choice == 'left':
|
||||
if self.mpu6500.acceleration()[0] >= 9:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@property
|
||||
def mpu9250_gyro(self):
|
||||
return self.mpu6500.gyro
|
||||
|
||||
def mpu9250_gyro_x(self):
|
||||
return self.mpu6500.gyro[0]
|
||||
|
||||
def mpu9250_gyro_y(self):
|
||||
return self.mpu6500.gyro[1]
|
||||
|
||||
def mpu9250_gyro_z(self):
|
||||
return self.mpu6500.gyro[2]
|
||||
|
||||
def mpu9250_gyro_values(self):
|
||||
return self.mpu6500.gyro
|
||||
|
||||
@property
|
||||
def mpu9250_magnetic(self):
|
||||
"""X, Y, Z axis micro-Tesla (uT) as floats."""
|
||||
return self.ak8963.magnetic
|
||||
|
||||
def mpu9250_magnetic_x(self):
|
||||
return self.mpu9250_magnetic[0]
|
||||
|
||||
def mpu9250_magnetic_y(self):
|
||||
return self.mpu9250_magnetic[1]
|
||||
|
||||
def mpu9250_magnetic_z(self):
|
||||
return self.mpu9250_magnetic[2]
|
||||
|
||||
def mpu9250_magnetic_values(self):
|
||||
return self.mpu9250_magnetic
|
||||
|
||||
# @property
|
||||
def mpu9250_get_field_strength(self):
|
||||
x=self.mpu9250_magnetic[0]
|
||||
y=self.mpu9250_magnetic[1]
|
||||
z=self.mpu9250_magnetic[2]
|
||||
return (x**2+y**2+z**2)**0.5*1000
|
||||
|
||||
def mpu9250_heading(self):
|
||||
x=self.mpu9250_magnetic[0]
|
||||
y=self.mpu9250_magnetic[1]
|
||||
z=self.mpu9250_magnetic[2]
|
||||
a=math.atan(z/x)
|
||||
b=math.atan(z/y)
|
||||
xr=x*math.cos(a)+y*math.sin(a)*math.sin(b)-z*math.cos(b)*math.sin(a)
|
||||
yr=x*math.cos(b)+z*math.sin(b)
|
||||
return 60*math.atan(yr/xr)
|
||||
|
||||
@property
|
||||
def whoami(self):
|
||||
return self.mpu6500.whoami
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exception_type, exception_value, traceback):
|
||||
pass
|
||||
|
||||
class Compass:
|
||||
RAD_TO_DEG = 57.295779513082320876798154814105
|
||||
|
||||
def __init__(self, sensor):
|
||||
self.sensor = sensor
|
||||
|
||||
def get_x(self):
|
||||
return self.sensor.mpu9250_magnetic[0]
|
||||
|
||||
def get_y(self):
|
||||
return self.sensor.mpu9250_magnetic[1]
|
||||
|
||||
def get_z(self):
|
||||
return self.sensor.mpu9250_magnetic[2]
|
||||
|
||||
def get_field_strength(self):
|
||||
return self.sensor.mpu9250_get_field_strength()
|
||||
|
||||
def heading(self):
|
||||
from math import atan2
|
||||
xyz = self.sensor.mpu9250_magnetic
|
||||
return int(((atan2(xyz[1], xyz[0]) * Compass.RAD_TO_DEG) + 180) % 360)
|
||||
|
||||
def calibrate(self):
|
||||
import matrix16x8
|
||||
mp_i2c=SoftI2C(scl = Pin(7), sda = Pin(6), freq = 400000)
|
||||
mp_matrix = matrix32x12.Matrix(mp_i2c)
|
||||
if self.is_calibrate() is False:
|
||||
# print('The calibration need to shaking in the air (e.g. 8 or 0) and waiting for a moment')
|
||||
print('First write 8 or 0 in the air with the board about 30 seconds, and then try to rotate the board in different direnctions several times.')
|
||||
mp_matrix.pixel(7, 3, 1)
|
||||
#mp_matrix.blink_rate(2)
|
||||
l1=0
|
||||
l2=0
|
||||
l3=0
|
||||
l4=0
|
||||
l5=0
|
||||
l6=0
|
||||
l7=0
|
||||
l8=0
|
||||
while True:
|
||||
x = self.sensor.mpu6500.acceleration()[0]
|
||||
y = self.sensor.mpu6500.acceleration()[1]
|
||||
z = self.sensor.mpu6500.acceleration()[2]
|
||||
a=(x**2+y**2+z**2)**0.5
|
||||
if z > 0:
|
||||
if x > 0 and y > 0 and a >= 12:
|
||||
l1=l1 + 1
|
||||
if x > 0 and y < 0 and a >= 12:
|
||||
l2=l2 + 1
|
||||
if x < 0 and y > 0 and a >= 12:
|
||||
l3=l3 + 1
|
||||
if x < 0 and y < 0 and a >= 12:
|
||||
l4=l4 + 1
|
||||
if z < 0:
|
||||
if x > 0 and y > 0 and a >= 12:
|
||||
l5=l5 + 1
|
||||
if x > 0 and y < 0 and a >= 12:
|
||||
l6=l6 + 1
|
||||
if x < 0 and y > 0 and a >= 12:
|
||||
l7=l7 + 1
|
||||
if x < 0 and y < 0 and a >= 12:
|
||||
l8=l8 + 1
|
||||
if l1 >= 2:
|
||||
mp_matrix.pixel(7, 0, 1)
|
||||
mp_matrix.pixel(8, 0, 1)
|
||||
mp_matrix.pixel(9, 1, 1)
|
||||
if l2 >= 2:
|
||||
mp_matrix.pixel(10, 2, 1)
|
||||
mp_matrix.pixel(10, 3, 1)
|
||||
if l3 >= 2:
|
||||
mp_matrix.pixel(10, 4, 1)
|
||||
mp_matrix.pixel(10, 5, 1)
|
||||
if l4 >= 2:
|
||||
mp_matrix.pixel(9, 6, 1)
|
||||
mp_matrix.pixel(8, 7, 1)
|
||||
if l5 >= 2:
|
||||
mp_matrix.pixel(7, 7, 1)
|
||||
mp_matrix.pixel(6, 7, 1)
|
||||
if l6 >= 2:
|
||||
mp_matrix.pixel(5, 6, 1)
|
||||
mp_matrix.pixel(4, 5, 1)
|
||||
if l7 >= 2:
|
||||
mp_matrix.pixel(4, 4, 1)
|
||||
mp_matrix.pixel(4, 3, 1)
|
||||
if l8 >= 2:
|
||||
mp_matrix.pixel(4, 2, 1)
|
||||
mp_matrix.pixel(5, 1, 1)
|
||||
mp_matrix.pixel(6, 0, 1)
|
||||
if l1>=2 and l2>=2 and l3>=2 and l4>=2 and l5>=2 and l6>=2 and l7>=2 and l8>=2:
|
||||
break
|
||||
else:
|
||||
self.sensor.ak8963.calibrate()
|
||||
with open("compass_cfg.py", "w") as f:
|
||||
f.write('\n_offset = ' + str(self.sensor.ak8963._offset) + '\n_scale = ' + str(self.sensor.ak8963._offset))
|
||||
else:
|
||||
print('The calibration configuration already exists. If you need to recalibrate, enter os.remove("compass_cfg.py") in repl and restart')
|
||||
try:
|
||||
import compass_cfg
|
||||
self.sensor.ak8963._offset = compass_cfg._offset
|
||||
self.sensor.ak8963._scale = compass_cfg._scale
|
||||
except Exception as e:
|
||||
print('compass_cfg error! delete it, please.')
|
||||
with open("compass_cfg.py") as f:
|
||||
for line in f:
|
||||
print(line)
|
||||
|
||||
def is_calibrate(self):
|
||||
try:
|
||||
import compass_cfg
|
||||
return True
|
||||
except Exception as e:
|
||||
return False
|
||||
|
||||
def reset_calibrate(self):
|
||||
import os
|
||||
os.remove("compass_cfg.py")
|
||||
137
mixly/boards/default/micropython/build/lib/ms32006.py
Normal file
137
mixly/boards/default/micropython/build/lib/ms32006.py
Normal file
@@ -0,0 +1,137 @@
|
||||
"""
|
||||
MS32006
|
||||
|
||||
Micropython library for the MS32006 step diever
|
||||
=======================================================
|
||||
#Changed from circuitpython to micropython 20211206
|
||||
#Fix register read / write bug 20211215
|
||||
dahanzimin From the Mixly Team
|
||||
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
|
||||
MS32006_REG_RESET = const(0x00) #复位
|
||||
MS32006_FCLK = const(25000000) #芯片输入时钟选择,此参数与运动速度有关。 范围是:5-30MHZ
|
||||
|
||||
ADDRESS_A = 0x10
|
||||
ADDRESS_B = 0x18
|
||||
MOT_FULL = 0
|
||||
MOT_HALF = 1
|
||||
MOT_A = 0
|
||||
MOT_B = 4
|
||||
MOT_N = 0
|
||||
MOT_CW = 1
|
||||
MOT_CCW = 2
|
||||
MOT_P = 3
|
||||
class MS32006:
|
||||
|
||||
_buffer = bytearray(2)
|
||||
|
||||
def __init__(self, i2c_bus,addr=ADDRESS_A,mode=MOT_FULL):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
self.reset()
|
||||
self.mode=mode
|
||||
|
||||
|
||||
def _read_u8(self, reg):
|
||||
return self._device.readfrom_mem(self._address, reg, 1)[0]
|
||||
|
||||
def _write_u8(self, reg, val):
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def reset(self):
|
||||
self._write_u8(MS32006_REG_RESET,0x00)
|
||||
time.sleep(0.1)
|
||||
self._write_u8(MS32006_REG_RESET,0xC1)
|
||||
|
||||
def move(self,moto,mot_dir,mot_pps,mot_step):
|
||||
readstate_0H = self._read_u8(0x00)
|
||||
readstate_9H = self._read_u8(0x09)
|
||||
speed_data=MS32006_FCLK//mot_pps//128 #设置速度 xx pps 128是固定参数
|
||||
|
||||
if speed_data<32: #限定转速
|
||||
speed_data=32
|
||||
elif speed_data>16383:
|
||||
speed_data=16383
|
||||
|
||||
mot_speed_l=speed_data&0x00ff #取低8位
|
||||
mot_speed_h=speed_data//0x100 #取高6位
|
||||
|
||||
if self.mode==MOT_FULL: #设置整步、半步驱动模式
|
||||
mot_speed_h|=0x80
|
||||
else:
|
||||
mot_speed_h&=0x7f
|
||||
|
||||
if mot_step>2047:
|
||||
raise AttributeError("Reach the set upper limit, up to 2047 step")
|
||||
|
||||
mot_step_l=mot_step&0x00ff
|
||||
mot_step_h=mot_step//0x100
|
||||
mot_step_h|=0x80
|
||||
|
||||
if mot_dir==MOT_CW:
|
||||
mot_step_h&=0xBF
|
||||
else:
|
||||
mot_step_h|=0x40
|
||||
self._write_u8(0x01+moto,mot_speed_l)
|
||||
self._write_u8(0x02+moto,mot_speed_h)
|
||||
self._write_u8(0x03+moto,mot_step_l)
|
||||
self._write_u8(0x04+moto,mot_step_h)
|
||||
|
||||
if moto==MOT_A:
|
||||
self._write_u8(0x00, readstate_0H&0xfb)
|
||||
self._write_u8(0x09, readstate_9H|0x80)
|
||||
else:
|
||||
self._write_u8(0x00, readstate_0H&0xfd)
|
||||
self._write_u8(0x09, readstate_9H|0x40)
|
||||
|
||||
def close(self,moto): #停止并关闭输出
|
||||
if moto==MOT_A:
|
||||
self._write_u8(0x04,0x00)
|
||||
else:
|
||||
self._write_u8(0x08,0x00)
|
||||
|
||||
def stop(self,moto): #此停止函数,强制让电机停止
|
||||
readstate = self._read_u8(0x00)
|
||||
if moto==MOT_A:
|
||||
self._write_u8(0x00,readstate|0x04)
|
||||
else:
|
||||
self._write_u8(0x00,readstate|0x02)
|
||||
|
||||
def readstep(self,moto): #读取电机运动步数
|
||||
if moto==MOT_A:
|
||||
rdb =self._read_u8(0x0b)
|
||||
rdc =self._read_u8(0x0c)
|
||||
else:
|
||||
rdb =self._read_u8(0x0d)
|
||||
rdc =self._read_u8(0x0e)
|
||||
return (rdb*0x100+rdc)&0xfff
|
||||
|
||||
def readbusy(self,moto): #读取电机缓存是否有数据
|
||||
if moto==MOT_A:
|
||||
busy =(self._read_u8(0x0b)>>6)&1
|
||||
else:
|
||||
busy =(self._read_u8(0x0d)>>6)&1
|
||||
return bool(busy)
|
||||
|
||||
def readwork(self,moto): #读取电机是否在运行
|
||||
if moto==MOT_A:
|
||||
busy =(self._read_u8(0x0b)>>4)&1
|
||||
else:
|
||||
busy =(self._read_u8(0x0d)>>4)&1
|
||||
return bool(busy)
|
||||
|
||||
def dc_motor(self,state,speed=100): #直流电机驱动
|
||||
if (state==MOT_CW) | (state==MOT_CCW) :
|
||||
speed_st=speed*127//100 |0x80
|
||||
self._write_u8(0x0A,speed_st)
|
||||
|
||||
readstate = self._read_u8(0x09) & 0xA0
|
||||
state_st=(state<<2) | 0X03 | readstate
|
||||
self._write_u8(0x09,state_st)
|
||||
|
||||
|
||||
|
||||
81
mixly/boards/default/micropython/build/lib/ms5611.py
Normal file
81
mixly/boards/default/micropython/build/lib/ms5611.py
Normal file
@@ -0,0 +1,81 @@
|
||||
import utime
|
||||
from micropython import const
|
||||
|
||||
_MS5611_ADDR = const(0x77)
|
||||
_CMD_ADC_READ = const(0x00)
|
||||
_CMD_RESET = const(0x1E)
|
||||
_CMD_CONVERT_D1 = const(0x40)
|
||||
_CMD_CONVERT_D2 = const(0x50)
|
||||
_CAL_DATA_C1 = const(0xA2)
|
||||
_CAL_DATA_C2 = const(0xA4)
|
||||
_CAL_DATA_C3 = const(0xA6)
|
||||
_CAL_DATA_C4 = const(0xA8)
|
||||
_CAL_DATA_C5 = const(0xAA)
|
||||
_CAL_DATA_C6 = const(0xAC)
|
||||
|
||||
# Oversampling settings
|
||||
OSR={"OSR_256":0, "OSR_512":2, "OSR_1024":4, "OSR_2048":6, "OSR_4096":8}
|
||||
|
||||
class MS5611:
|
||||
def __init__(self, i2c_bus, addr=_MS5611_ADDR, osr='OSR_4096'):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
self._wreg(_CMD_RESET)
|
||||
utime.sleep_ms(50)
|
||||
|
||||
self.c1 = self._rreg(_CAL_DATA_C1, 2)
|
||||
self.c2 = self._rreg(_CAL_DATA_C2, 2)
|
||||
self.c3 = self._rreg(_CAL_DATA_C3, 2)
|
||||
self.c4 = self._rreg(_CAL_DATA_C4, 2)
|
||||
self.c5 = self._rreg(_CAL_DATA_C5, 2)
|
||||
self.c6 = self._rreg(_CAL_DATA_C6, 2)
|
||||
self.pressure_cmd_rate = _CMD_CONVERT_D1 + OSR[osr]
|
||||
self.temp_cmd_rate = _CMD_CONVERT_D2 + OSR[osr]
|
||||
|
||||
def _wreg(self, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto(self._address, bytes([val]))
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
return int.from_bytes(self._device.readfrom_mem(self._address, reg, nbytes), 'big')
|
||||
|
||||
@property
|
||||
def getdata(self):
|
||||
'''处理获取数据'''
|
||||
self._wreg(self.pressure_cmd_rate)
|
||||
utime.sleep_ms(15)
|
||||
D1 = self._rreg(_CMD_ADC_READ, 3)
|
||||
|
||||
self._wreg(self.temp_cmd_rate)
|
||||
utime.sleep_ms(15)
|
||||
D2 = self._rreg(_CMD_ADC_READ, 3)
|
||||
|
||||
dT = D2 - self.c5 * 2 ** 8
|
||||
TEMP = 2000 + dT * self.c6 / 2 ** 23
|
||||
OFF = self.c2 * 2 ** 16 + dT * self.c4 / 2 ** 7
|
||||
SENS = self.c1 * 2 ** 15 + dT * self.c3 / 2 ** 8
|
||||
|
||||
if TEMP < 2000:
|
||||
T2 = dT * dT / 2 ** 31
|
||||
OFF2 = 5 * (TEMP - 2000) ** 2 / 2
|
||||
SENS2 = 5 * (TEMP - 2000) ** 2 / 4
|
||||
if TEMP < -1500:
|
||||
OFF2 = OFF2 + 7 * (TEMP + 1500) ** 2
|
||||
SENS2 = SENS2 + 11 * (TEMP + 1500) ** 2 / 2
|
||||
TEMP = TEMP - T2
|
||||
OFF = OFF - OFF2
|
||||
SENS = SENS - SENS2
|
||||
|
||||
P = (D1 * SENS / 2 ** 21 - OFF) / 2 ** 15
|
||||
H = (1 - (P / 101325) ** (1 / 5.255)) * 44330
|
||||
return round(P / 100, 2), round(TEMP / 100, 2), round(H, 2)
|
||||
|
||||
def pressure(self):
|
||||
return self.getdata[0]
|
||||
|
||||
def temperature(self):
|
||||
return self.getdata[1]
|
||||
|
||||
def altitude(self, reference=1013.25):
|
||||
return (pow((reference / 33.8639), 0.190255) - pow((self.getdata[0] / 33.8639), 0.190255)) / 0.000013125214
|
||||
57
mixly/boards/default/micropython/build/lib/msa301.py
Normal file
57
mixly/boards/default/micropython/build/lib/msa301.py
Normal file
@@ -0,0 +1,57 @@
|
||||
"""
|
||||
MSA301
|
||||
|
||||
Micropython library for the MSA301 Accelerometer
|
||||
=======================================================
|
||||
#Preliminary composition 20220817
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
MSA301_ADDRESS = const(0x26)
|
||||
MSA301_REG_DEVICE_ID = const(0x01)
|
||||
MSA301_REG_DATA = const(0x02)
|
||||
MSA301_REG_ODR = const(0x10)
|
||||
MSA301_REG_POWERMODE = const(0x11)
|
||||
MSA301_REG_RESRANGE = const(0x0F)
|
||||
|
||||
class MSA301:
|
||||
def __init__(self, i2c_bus, front=False):
|
||||
self._device = i2c_bus
|
||||
self._address = MSA301_ADDRESS
|
||||
self._front = front
|
||||
if self._chip_id() != 0x13:
|
||||
raise AttributeError("Cannot find a MSA301")
|
||||
|
||||
self._wreg(MSA301_REG_ODR,0X09) #RATE_500_HZ
|
||||
self._wreg(MSA301_REG_POWERMODE,0X12) #NORMAL & WIDTH_250_HZ
|
||||
self._wreg(MSA301_REG_RESRANGE,0X02) #RESOLUTION_14_BIT & RANGE_8_G
|
||||
|
||||
def _rreg(self, reg,nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _chip_id(self):
|
||||
return self._rreg(MSA301_REG_DEVICE_ID)
|
||||
|
||||
def u2s(self,n):
|
||||
return n if n < (1 << 7) else n - (1 << 8)
|
||||
|
||||
def acceleration(self):
|
||||
data_reg=self._rreg(MSA301_REG_DATA,6)
|
||||
x_acc=((self.u2s(data_reg[1])<<8|data_reg[0])>>2)/1024.0
|
||||
y_acc=((self.u2s(data_reg[3])<<8|data_reg[2])>>2)/1024.0
|
||||
z_acc=((self.u2s(data_reg[5])<<8|data_reg[4])>>2)/1024.0
|
||||
return (-y_acc,-x_acc,z_acc) if self._front else (y_acc,-x_acc,z_acc)
|
||||
|
||||
def eulerangles(self,upright=False):
|
||||
x,y,z=self.acceleration()
|
||||
pitch = degrees(atan(z / sqrt(x ** 2 + y ** 2))) if upright else degrees(atan(y / sqrt(x ** 2 + z ** 2)))
|
||||
roll = degrees(atan(x / sqrt(y ** 2 + z ** 2)))
|
||||
return round(pitch,2),round(roll,2)
|
||||
174
mixly/boards/default/micropython/build/lib/music.py
Normal file
174
mixly/boards/default/micropython/build/lib/music.py
Normal file
@@ -0,0 +1,174 @@
|
||||
"""
|
||||
Music buzzer
|
||||
|
||||
Micropython library for the Music buzzer
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import _thread, gc
|
||||
from time import sleep_ms
|
||||
from machine import Pin, PWM
|
||||
|
||||
normal_tone = {
|
||||
'A1': 55, 'B1': 62, 'C1': 33, 'D1': 37, 'E1': 41, 'F1': 44, 'G1': 49,
|
||||
'A2': 110, 'B2': 123, 'C2': 65, 'D2': 73, 'E2': 82, 'F2': 87, 'G2': 98,
|
||||
'A3': 220, 'B3': 247, 'C3': 131, 'D3': 147, 'E3': 165, 'F3': 175, 'G3': 196,
|
||||
'A4': 440, 'B4': 494, 'C4': 262, 'D4': 294, 'E4': 330, 'F4': 349, 'G4': 392,
|
||||
'A5': 880, 'B5': 988, 'C5': 523, 'D5': 587, 'E5': 659, 'F5': 698, 'G5': 784,
|
||||
'A6': 1760, 'B6': 1976, 'C6': 1047, 'D6': 1175, 'E6': 1319, 'F6': 1397, 'G6': 1568,
|
||||
'A7': 3520, 'B7': 3951, 'C7': 2093, 'D7': 2349, 'E7': 2637, 'F7': 2794, 'G7': 3135,
|
||||
'A8': 7040, 'B8': 7902, 'C8': 4186, 'D8': 4699, 'E8': 5274, 'F8': 5588, 'G8': 6271,
|
||||
'A9': 14080, 'B9': 15804 }
|
||||
|
||||
Letter = 'ABCDEFG#R'
|
||||
|
||||
class MIDI():
|
||||
def __init__(self, pin, volume=100, invert=0, pa_ctrl=None):
|
||||
self.reset()
|
||||
self._invert = invert
|
||||
self._pin = pin
|
||||
self._volume = volume
|
||||
self._play = False
|
||||
self._over = True
|
||||
self._pwm = None
|
||||
self._pa_ctrl = pa_ctrl
|
||||
|
||||
def set_volume(self, volume):
|
||||
if not 0 <= volume <= 100:
|
||||
raise ValueError("Volume value is in the range: 0-100")
|
||||
self._volume=volume
|
||||
|
||||
def set_tempo(self, ticks=4, bpm=120):
|
||||
self.ticks = ticks
|
||||
self.bpm = bpm
|
||||
self.beat = 60000 / self.bpm / self.ticks
|
||||
|
||||
def set_octave(self, octave=4):
|
||||
self.octave = octave
|
||||
|
||||
def set_duration(self, duration=4):
|
||||
self.duration = duration
|
||||
|
||||
def get_tempo(self):
|
||||
return (self.ticks, self.bpm)
|
||||
|
||||
def get_octave(self):
|
||||
return self.octave
|
||||
|
||||
def get_duration(self):
|
||||
return self.duration
|
||||
|
||||
def reset(self):
|
||||
self.set_duration()
|
||||
self.set_octave()
|
||||
self.set_tempo()
|
||||
|
||||
def parse(self, tone, dict):
|
||||
time = self.beat * self.duration
|
||||
pos = tone.find(':')
|
||||
if pos != -1:
|
||||
time = self.beat * int(tone[(pos + 1):])
|
||||
tone = tone[:pos]
|
||||
freq, tone_size = 1, len(tone)
|
||||
if 'R' in tone:
|
||||
freq = 400000
|
||||
elif tone_size == 1:
|
||||
freq = dict[tone[0] + str(self.octave)]
|
||||
elif tone_size == 2:
|
||||
freq = dict[tone]
|
||||
self.set_octave(tone[1:])
|
||||
return int(freq), int(time)
|
||||
|
||||
def midi(self, tone):
|
||||
pos = tone.find('#')
|
||||
if pos != -1:
|
||||
return self.parse(tone.replace('#', ''), normal_tone)
|
||||
pos = tone.find('B')
|
||||
if pos != -1 and pos != 0:
|
||||
return self.parse(tone.replace('B', ''), normal_tone)
|
||||
return self.parse(tone, normal_tone)
|
||||
|
||||
def set_default(self, tone):
|
||||
pos = tone.find(':')
|
||||
if pos != -1:
|
||||
self.set_duration(int(tone[(pos + 1):]))
|
||||
tone = tone[:pos]
|
||||
|
||||
def play(self, tune, duration=None, pa_delay=100):
|
||||
if self._pa_ctrl: self._pa_ctrl(1, pa_delay)
|
||||
self._pwm = PWM(Pin(self._pin), duty=1023 if self._invert else 0)
|
||||
self._play = True
|
||||
self._over = False
|
||||
if duration is None:
|
||||
self.set_default(tune[0])
|
||||
else:
|
||||
self.set_duration(duration)
|
||||
for tone in tune:
|
||||
tone = tone.upper()
|
||||
if not self._play:
|
||||
break
|
||||
if tone[0] not in Letter:
|
||||
continue
|
||||
midi = self.midi(tone)
|
||||
if self._play: self._pwm.duty((1023-self._volume) if self._invert else self._volume)
|
||||
if self._play: self._pwm.freq(midi[0])
|
||||
sleep_ms(midi[1])
|
||||
if self._play: self._pwm.freq(400000)
|
||||
sleep_ms(1)
|
||||
if self._pa_ctrl: self._pa_ctrl(0, 0)
|
||||
self._pwm.deinit()
|
||||
sleep_ms(10)
|
||||
self._over = True
|
||||
|
||||
def play_thread(self, tune, duration=None, pa_delay=100):
|
||||
self._play = False
|
||||
while not self._over:
|
||||
sleep_ms(10)
|
||||
if not self._play:
|
||||
gc.collect()
|
||||
_thread.start_new_thread(self.play, (tune, duration, pa_delay))
|
||||
sleep_ms(100)
|
||||
|
||||
def pitch(self, freq, pa_delay=100):
|
||||
if self._pa_ctrl: self._pa_ctrl(1, pa_delay)
|
||||
self._pwm = PWM(Pin(self._pin))
|
||||
self._pwm.duty((1023-self._volume) if self._invert else self._volume)
|
||||
self._pwm.freq(int(freq))
|
||||
|
||||
def pitch_time(self, freq, delay, pa_delay=100):
|
||||
if self._pa_ctrl: self._pa_ctrl(1, pa_delay)
|
||||
self._pwm = PWM(Pin(self._pin))
|
||||
self._pwm.duty((1023-self._volume) if self._invert else self._volume)
|
||||
self._pwm.freq(int(freq))
|
||||
sleep_ms(delay)
|
||||
if self._pa_ctrl: self._pa_ctrl(0, 0)
|
||||
self._pwm.deinit()
|
||||
sleep_ms(10)
|
||||
|
||||
def stop(self):
|
||||
self._play = False
|
||||
if self._pa_ctrl: self._pa_ctrl(0, 0)
|
||||
if self._pwm: self._pwm.deinit()
|
||||
sleep_ms(10)
|
||||
|
||||
DADADADUM=['r4:2','g','g','g','eb:8','r:2','f','f','f','d:8']
|
||||
ENTERTAINER=['d4:1','d#','e','c5:2','e4:1','c5:2','e4:1','c5:3','c:1','d','d#','e','c','d','e:2','b4:1','d5:2','c:4']
|
||||
PRELUDE=['c4:1','e','g','c5','e','g4','c5','e','c4','e','g','c5','e','g4','c5','e','c4','d','g','d5','f','g4','d5','f','c4','d','g','d5','f','g4','d5','f','b3','d4','g','d5','f','g4','d5','f','b3','d4','g','d5','f','g4','d5','f','c4','e','g','c5','e','g4','c5','e','c4','e','g','c5','e','g4','c5','e']
|
||||
ODE=['e4','e','f','g','g','f','e','d','c','c','d','e','e:6','d:2','d:8','e:4','e','f','g','g','f','e','d','c','c','d','e','d:6','c:2','c:8']
|
||||
NYAN=['f#5:1','g#','c#:1','d#:2','b4:1','d5:1','c#','b4:2','b','c#5','d','d:1','c#','b4:1','c#5:1','d#','f#','g#','d#','f#','c#','d','b4','c#5','b4','d#5:2','f#','g#:1','d#','f#','c#','d#','b4','d5','d#','d','c#','b4','c#5','d:2','b4:1','c#5','d#','f#','c#','d','c#','b4','c#5:2','b4','c#5','b4','f#:1','g#','b:2','f#:1','g#','b','c#5','d#','b4','e5','d#','e','f#','b4:2','b','f#:1','g#','b','f#','e5','d#','c#','b4','f#','d#','e','f#','b:2','f#:1','g#','b:2','f#:1','g#','b','b','c#5','d#','b4','f#','g#','f#','b:2','b:1','a#','b','f#','g#','b','e5','d#','e','f#','b4:2','c#5']
|
||||
RINGTONE=['c4:1','d','e:2','g','d:1','e','f:2','a','e:1','f','g:2','b','c5:4']
|
||||
FUNK=['c2:2','c','d#','c:1','f:2','c:1','f:2','f#','g','c','c','g','c:1','f#:2','c:1','f#:2','f','d#']
|
||||
BLUES=['c2:2','e','g','a','a#','a','g','e','c2:2','e','g','a','a#','a','g','e','f','a','c3','d','d#','d','c','a2','c2:2','e','g','a','a#','a','g','e','g','b','d3','f','f2','a','c3','d#','c2:2','e','g','e','g','f','e','d']
|
||||
BIRTHDAY=['c4:4','c:1','d:4','c:4','f','e:8','c:3','c:1','d:4','c:4','g','f:8','c:3','c:1','c5:4','a4','f','e','d','a#:3','a#:1','a:4','f','g','f:8']
|
||||
WEDDING=['c4:4','f:3','f:1','f:8','c:4','g:3','e:1','f:8','c:4','f:3','a:1','c5:4','a4:3','f:1','f:4','e:3','f:1','g:8']
|
||||
FUNERAL=['c3:4','c:3','c:1','c:4','d#:3','d:1','d:3','c:1','c:3','b2:1','c3:4']
|
||||
PUNCHLINE=['c4:3','g3:1','f#','g','g#:3','g','r','b','c4']
|
||||
PYTHON=['d5:1','b4','r','b','b','a#','b','g5','r','d','d','r','b4','c5','r','c','c','r','d','e:5','c:1','a4','r','a','a','g#','a','f#5','r','e','e','r','c','b4','r','b','b','r','c5','d:5','d:1','b4','r','b','b','a#','b','b5','r','g','g','r','d','c#','r','a','a','r','a','a:5','g:1','f#:2','a:1','a','g#','a','e:2','a:1','a','g#','a','d','r','c#','d','r','c#','d:2','r:3']
|
||||
BADDY=['c3:3','r','d:2','d#','r','c','r','f#:8']
|
||||
CHASE=['a4:1','b','c5','b4','a:2','r','a:1','b','c5','b4','a:2','r','a:2','e5','d#','e','f','e','d#','e','b4:1','c5','d','c','b4:2','r','b:1','c5','d','c','b4:2','r','b:2','e5','d#','e','f','e','d#','e']
|
||||
BA_DING=['b5:1','e6:3']
|
||||
WAWAWAWAA=['e3:3','r:1','d#:3','r:1','d:4','r:1','c#:8']
|
||||
JUMP_UP=['c5:1','d','e','f','g']
|
||||
JUMP_DOWN=['g5:1','f','e','d','c']
|
||||
POWER_UP=['g4:1','c5','e4','g5:2','e5:1','g5:3']
|
||||
POWER_DOWN=['g5:1','d#','c','g4:2','b:1','c5:3']
|
||||
91
mixly/boards/default/micropython/build/lib/mxc6655xa.py
Normal file
91
mixly/boards/default/micropython/build/lib/mxc6655xa.py
Normal file
@@ -0,0 +1,91 @@
|
||||
"""
|
||||
MXC6655XA
|
||||
|
||||
Micropython library for the MXC6655XA Accelerometer
|
||||
=======================================================
|
||||
#Changed from circuitpython to micropython 20220224
|
||||
#Format unified 20220623
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from math import atan,sqrt,degrees
|
||||
from micropython import const
|
||||
|
||||
MXC6655XA_ADDRESS = const(0x15)
|
||||
MXC6655XA_REG_DATA = const(0x03)
|
||||
MXC6655XA_REG_CTRL = const(0x0D)
|
||||
MXC6655XA_REG_DEVICE_ID = const(0x0E)
|
||||
MXC6655XA_CMD_8G_POWER_ON = const(0x40)
|
||||
MXC6655XA_CMD_4G_POWER_ON = const(0x20)
|
||||
MXC6655XA_CMD_2G_POWER_ON = const(0x00)
|
||||
|
||||
_Range = (
|
||||
MXC6655XA_CMD_2G_POWER_ON, # 2g
|
||||
MXC6655XA_CMD_4G_POWER_ON, # 4g
|
||||
MXC6655XA_CMD_8G_POWER_ON, # 8g
|
||||
)
|
||||
|
||||
_Range_X = (
|
||||
1024, # 2g
|
||||
512, # 4g
|
||||
256, # 8g
|
||||
)
|
||||
|
||||
MXC6655XA_T_ZERO =25
|
||||
MXC6655XA_T_SENSITIVITY =0.586
|
||||
|
||||
class MXC6655XA:
|
||||
|
||||
def __init__(self,i2c_bus,set_range=2, front=False):
|
||||
self._device = i2c_bus
|
||||
self._address = MXC6655XA_ADDRESS
|
||||
self._range = set_range #default 8g range
|
||||
self._front = front
|
||||
|
||||
if self._chip_id() != 0x02:
|
||||
raise AttributeError("Cannot find a MXC6655XA")
|
||||
self._Enable() #star
|
||||
#time.sleep(0.3)
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg,nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _chip_id(self):
|
||||
return self._rreg(MXC6655XA_REG_DEVICE_ID)
|
||||
|
||||
def _Enable(self):
|
||||
self._wreg(MXC6655XA_REG_CTRL,_Range[self._range])
|
||||
|
||||
def u2s(self,n):
|
||||
return n if n < (1 << 7) else n - (1 << 8)
|
||||
|
||||
@property
|
||||
def getdata(self):
|
||||
data_reg=self._rreg(MXC6655XA_REG_DATA,7)
|
||||
x_acc=float((self.u2s(data_reg[0])<<8|data_reg[1])>>4)/_Range_X[self._range]
|
||||
y_acc=float((self.u2s(data_reg[2])<<8|data_reg[3])>>4)/_Range_X[self._range]
|
||||
z_acc=float((self.u2s(data_reg[4])<<8|data_reg[5])>>4)/_Range_X[self._range]
|
||||
t_acc=float(self.u2s(data_reg[6]))*MXC6655XA_T_SENSITIVITY + MXC6655XA_T_ZERO
|
||||
return (-y_acc,-x_acc,z_acc,round(t_acc,1)) if self._front else (y_acc,-x_acc,z_acc,round(t_acc,1))
|
||||
|
||||
def acceleration(self):
|
||||
return self.getdata[0:3]
|
||||
|
||||
def strength(self):
|
||||
from math import sqrt
|
||||
return sqrt(self.getdata[0]**2+self.getdata[1]**2+self.getdata[2]**2)
|
||||
|
||||
def temperature(self):
|
||||
return self.getdata[3]
|
||||
|
||||
def eulerangles(self,upright=False):
|
||||
x,y,z=self.acceleration()
|
||||
pitch = degrees(atan(z / sqrt(x ** 2 + y ** 2))) if upright else degrees(atan(y / sqrt(x ** 2 + z ** 2)))
|
||||
roll = degrees(atan(x / sqrt(y ** 2 + z ** 2)))
|
||||
return round(pitch,2),round(roll,2)
|
||||
117
mixly/boards/default/micropython/build/lib/ns9300.py
Normal file
117
mixly/boards/default/micropython/build/lib/ns9300.py
Normal file
@@ -0,0 +1,117 @@
|
||||
"""
|
||||
NS9300
|
||||
|
||||
Micropython library for the NS9300(Music Player)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
_PLAY_CTRL = const(0x04)
|
||||
_PLAY_VOL = const(0x06)
|
||||
_PLAY_INS = const(0x09)
|
||||
_PLAY_MODE = const(0x0B)
|
||||
|
||||
class NS9300:
|
||||
def __init__(self, uart, delay=250):
|
||||
self._uart = uart
|
||||
self._delay = delay
|
||||
self._uart.init(baudrate=9600, timeout_char=5)
|
||||
if not self._chip_id():
|
||||
raise AttributeError("Cannot find a NS930x")
|
||||
|
||||
def _wreg(self, cmd, data=b'\x00'):
|
||||
'''Write memory address'''
|
||||
_buf = bytearray([cmd, 255 - cmd, len(data)]) + data
|
||||
eec = 0
|
||||
for i in range(len(_buf)):
|
||||
eec += _buf[i]
|
||||
_buf.append(eec & 0xFF)
|
||||
#print("TX:", bytes(_buf), len(_buf))
|
||||
self._uart.write(_buf)
|
||||
|
||||
def _rreg(self, cmd):
|
||||
'''read memory address'''
|
||||
time.sleep_ms(self._delay)
|
||||
if self._uart.any():
|
||||
_buf = self._uart.read()
|
||||
#print("RX:", _buf, len(_buf))
|
||||
if _buf[0] == 0xAA and _buf[1] == 0x55:
|
||||
raise OSError("Play Error", _buf[4])
|
||||
elif _buf[0] == cmd and _buf[0] == (255 - _buf[1]):
|
||||
#eec = 0
|
||||
#for i in range(len(_buf) - 1):
|
||||
#eec += _buf[i]
|
||||
#if (eec & 0xFF) == _buf[-1]:
|
||||
return _buf[3:3 + _buf[2]]
|
||||
|
||||
def _chip_id(self):
|
||||
'''复位指令有问题,暂停止播放态处理'''
|
||||
for _ in range(10):
|
||||
self._wreg(_PLAY_CTRL, b'\x03')
|
||||
if self._rreg(_PLAY_CTRL):
|
||||
return True
|
||||
|
||||
def _ascll(self, data):
|
||||
'''获取ASCLL字节,剔除中文'''
|
||||
_strs=''
|
||||
for char in data:
|
||||
_strs += char if ord(char) <= 0xFF else "*"
|
||||
return _strs.encode()
|
||||
|
||||
def status(self, value=1):
|
||||
"""0已停止? 1播放中? 2已暂停?"""
|
||||
return self.control(0) == value
|
||||
|
||||
def control(self, value=0):
|
||||
"""0查询(0停止 1播放 2暂停) 1播放 2暂停 3停止 4上一曲 5下一曲 6总曲数 7当前曲"""
|
||||
self._wreg(_PLAY_CTRL, (value if value <= 5 else value + 7).to_bytes(1, 'little'))
|
||||
_dat = self._rreg(_PLAY_CTRL)
|
||||
if _dat:
|
||||
return _dat[1] if value <= 3 else _dat[1] << 8 | _dat[2]
|
||||
|
||||
def play(self, value='m*.mp3'):
|
||||
"""int播放曲目 str播放文件(*省略,GBK编码MPY不支持)"""
|
||||
if isinstance(value, int):
|
||||
self._wreg(_PLAY_CTRL, b'\x06' + value.to_bytes(2, 'big'))
|
||||
elif isinstance(value, str):
|
||||
self._wreg(_PLAY_CTRL, b'\x07' + self._ascll(value))
|
||||
else:
|
||||
raise ValueError("Input format error")
|
||||
_dat = self._rreg(_PLAY_CTRL)
|
||||
if _dat:
|
||||
return _dat[1] << 8 | _dat[2]
|
||||
|
||||
def insert(self, value='m*.mp3'):
|
||||
"""int播放曲目 str播放文件(*省略,GBK编码MPY不支持)"""
|
||||
if isinstance(value, int):
|
||||
self._wreg(_PLAY_INS, b'\x00\x02' + value.to_bytes(2, 'big'))
|
||||
elif isinstance(value, str):
|
||||
self._wreg(_PLAY_INS, b'\x01\x02' + self._ascll(value))
|
||||
else:
|
||||
raise ValueError("Input format error")
|
||||
time.sleep_ms(self._delay)
|
||||
|
||||
def volume(self, value=None):
|
||||
"""None返回音量 int设置音量(0~30)"""
|
||||
if value is None:
|
||||
self._wreg(_PLAY_VOL, b'\x00')
|
||||
_dat = self._rreg(_PLAY_VOL)
|
||||
if _dat:
|
||||
return _dat[1]
|
||||
else:
|
||||
value = min(30, max(0, value))
|
||||
self._wreg(_PLAY_VOL, b'\x01' + value.to_bytes(1, 'little'))
|
||||
time.sleep_ms(self._delay)
|
||||
|
||||
def mode(self, value=None):
|
||||
"""0全部循环 1单曲循环 2目录循环 3随机播放 4单曲停止 5顺序播放"""
|
||||
if value is None:
|
||||
self._wreg(_PLAY_MODE, b'\x00')
|
||||
_dat = self._rreg(_PLAY_MODE)
|
||||
if _dat:
|
||||
return _dat[1]
|
||||
else:
|
||||
self._wreg(_PLAY_MODE, b'\x01' + value.to_bytes(1, 'little'))
|
||||
time.sleep_ms(self._delay)
|
||||
46
mixly/boards/default/micropython/build/lib/ntptime.py
Normal file
46
mixly/boards/default/micropython/build/lib/ntptime.py
Normal file
@@ -0,0 +1,46 @@
|
||||
import utime,gc
|
||||
from machine import RTC
|
||||
import usocket as socket
|
||||
import ustruct as struct
|
||||
|
||||
# NTP_DELTA (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
|
||||
NTP_DELTA=3155673600
|
||||
|
||||
def time(host="pool.ntp.org", utc=28800, times=5):
|
||||
for _ in range(times):
|
||||
try:
|
||||
NTP_QUERY = bytearray(48)
|
||||
NTP_QUERY[0] = 0x1B
|
||||
addr = socket.getaddrinfo(host, 123)[0][-1]
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
try:
|
||||
s.settimeout(1)
|
||||
res = s.sendto(NTP_QUERY, addr)
|
||||
msg = s.recv(48)
|
||||
finally:
|
||||
del addr
|
||||
s.close()
|
||||
gc.collect()
|
||||
val = struct.unpack("!I", msg[40:44])[0]
|
||||
return utime.gmtime(val - NTP_DELTA + utc)
|
||||
except Exception as e:
|
||||
error = e
|
||||
utime.sleep(0.1)
|
||||
raise OSError('Error fetching network time', error)
|
||||
|
||||
# There's currently no timezone support in MicroPython, and the RTC is set in UTC time.
|
||||
def settime(times):
|
||||
if isinstance(times, str):
|
||||
try:
|
||||
val = eval(times)
|
||||
if len(val) >= 6:
|
||||
times=(val[0], val[1], val[2], val[3], val[4], val[5], 0)
|
||||
else:
|
||||
raise ValueError("Clock information format error")
|
||||
except:
|
||||
raise ValueError("Clock information format error, use ',' to separate at least 6 numerical values")
|
||||
if type(times) in (tuple, list):
|
||||
if 6 <= len(times) <= 8:
|
||||
RTC().datetime((times[0], times[1], times[2], 0, times[3], times[4], times[5], 0))
|
||||
else:
|
||||
raise ValueError("Settime needs a tuple of length 6~8")
|
||||
18
mixly/boards/default/micropython/build/lib/object_picture.py
Normal file
18
mixly/boards/default/micropython/build/lib/object_picture.py
Normal file
@@ -0,0 +1,18 @@
|
||||
#Take the picture bytes in object_picture.py
|
||||
#--dahanzimin From the Mixly Team
|
||||
|
||||
Bomb=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x0e\x00\xc0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x02\x00\x80\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x03\x00\x80\x18\x00\x00\x00\x00\x00\x7f\x00\x00\x01\x80\x800\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x80\x80`\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x80\x80\xc0\x00\x00\x00\x00\x00\x7f\x00\x00\x00A\x01\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00 \x02\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00 \x04\x00\x00\x00\x00\x00\x00\x7f\x00\x00@\x11\x18\x00\x00\x00\x00\x00\x00\x7f\x00\x00p\x000\x00\x00\x00\x00\x00\x00\x7f\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x02\x80\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00#\xfe\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xe0\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x7f\x00\x00\x00@\x00\x06\x00\x00\x00\x00\x00\x7f\x00\x00\x01\x00\x00\x03\xf8\x00\x00\x00\x00\x7f\x00\x00\x06\x00\x00\x01\xf8\x00\x00\x00\x00\x7f\x00\x000\x08\x00\x03\xfc\x00\x00\x00\x00\x7f\x00\x01\xe0\x10\x00\x07\xfc\x00\x00\x00\x00\x7f\x00\x03\x00\x00\x80\x03\xff\xfe\x00\x00\x00\x7f\x00\x00\x000\x00\x03\xff\xff\xc0\x00\x00\x7f\x00\x00\x00 @\x01\xff\xfcp\x00\x00\x7f\x00\x00\x00@@\x03\xff\xff\x18\x00\x00\x7f\x00\x00\x00@@\x03\xff\xff\xcc\x00\x00\x7f\x00\x00\x00\xc0@\x07\xff\xff\xe6\x00\x00\x7f\x00\x00\x00\x00`\x0f\xff\xff\xf3\x00\x00\x7f\x00\x00\x00\x00 \x1f\xff\xff\xf1\x80\x00\x7f\x00\x00\x00\x00 ?\xff\xff\xf9\x80\x00\x7f\x00\x00\x00\x000?\xff\xff\xff\xc0\x00\x7f\x00\x00\x00\x000\x7f\xff\xff\xff\xc0\x00\x7f\x00\x00\x00\x00\x10\x7f\xff\xff\xff\xe0\x00\x7f\x00\x00\x00\x00\x00\xff\xff\xff\xff\xe0\x00\x7f\x00\x00\x00\x00\x00\xff\xff\xff\xff\xe0\x00\x7f\x00\x00\x00\x00\x00\xff\xff\xff\xff\xe0\x00\x7f\x00\x00\x00\x00\x00\xff\xff\xff\xff\xf0\x00\x7f\x00\x00\x00\x00\x00\xff\xff\xff\xff\xf0\x00\x7f\x00\x00\x00\x00\x00\xff\xff\xff\xff\xf0\x00\x7f\x00\x00\x00\x00\x00\xff\xff\xff\xff\xf0\x00\x7f\x00\x00\x00\x00\x00\xff\xff\xff\xff\xf0\x00\x7f\x00\x00\x00\x00\x00\xff\xff\xff\xff\xe0\x00\x7f\x00\x00\x00\x00\x00\xff\xff\xff\xff\xe0\x00\x7f\x00\x00\x00\x00\x00\xff\xff\xff\xff\xe0\x00\x7f\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xe0\x00\x7f\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xc0\x00\x7f\x00\x00\x00\x00\x00?\xff\xff\xff\xc0\x00\x7f\x00\x00\x00\x00\x00?\xff\xff\xff\x80\x00\x7f\x00\x00\x00\x00\x00\x1f\xff\xff\xff\x80\x00\x7f\x00\x00\x00\x00\x00\x1f\xff\xff\xff\x00\x00\x7f\x00\x00\x00\x00\x00\x0f\xff\xff\xfe\x00\x00\x7f\x00\x00\x00\x00\x00\x07\xff\xff\xfc\x00\x00\x7f\x00\x00\x00\x00\x00\x03\xff\xff\xf8\x00\x00\x7f\x00\x00\x00\x00\x00\x00\xff\xff\xe0\x00\x00\x7f\x00\x00\x00\x00\x00\x00?\xff\xc0\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x0f\xfe\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Boom=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00`\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00p\x00\x06\x00\x00\x00\x00\x7f\x00\x00\x00\x00X\x00\x0e\x00\x00\x00\x00\x7f\x00\x00\x00\x00x\x00\x16\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xcc\x00:\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xae\x00g\x00\x00\x00\x00\x7f\x00\x00\x80\x01\x96\x00k\x00\x00\x00\x00\x7f\x00\x00\xc0\x01\xab\x81\xd5\x00\x00\x00\x00\x7f\x00\x00|\x03U\xff\xa5\x80\x00\x00\x00\x7f\x00\x00v\x06\xaa\xffU\x80\x00\x00\x00\x7f\x00\x00;\xfe\xa9~\xaa\xc3\x02\x00\x00\x7f\x00\x005\xfdU\x02U`\x0c\x00\x00\x7f\x00\x00\x1a\xaa\xaa\xaa\xaa\xb8x\x00\x04\x7f\x01\x00\x15T\xaa\xaa\xa9_\xf0\x00\x04\x7f\x00\x00\x19URT\xa6\xa2\xb0\x00\x00\x7f\x00\x00\x1a\xaa\xa9J\x95\x15`\x00\x00\x7f\x00\x00\x1a\xaa^\xb5n\xea`\x00\x00\x7f\x00\x009U_\x85\x1e\x15\xc0\x00\x00\x7f\x00\x00:\xaa\xae\xf8{\xea\xc0\x00\x00\x7f\x00\x00z\xaa\xad\x7f\xea\xea\xc0\x00\x00\x7f\x00\x01\xf5U.\xaf\xd5u\x80\x00\x00\x7f\x00\x01\xea\xaa\xadj\xaa\xeb\x80\x00\x00\x7f\x00\x0f\xea\xaa\xae\x95UU\x80\x00\x00\x7f\x07\xff\xaaUUe\xaa\xd5\xc0\x00\x00\x7f\x01\xfe\xaa\xa0\x0e\x9auj\xc0\x00\x00\x7f\x00:\xa9_\xf5\xe3\xea\xd5\xc0\x00\x00\x7f\x00\x0e*\xaf\xea\xdeuU`\x00\x00\x7f\x00\x03\x95V\xaa\x80j\xea\xb0\x00\x00\x7f\x00\x01\xea\xabU\x80j\xb5x\x00\x00\x7f\x00\x00\xea\xa9\xaa\x80*\xba\x9c\x00\x00\x7f\x00\x009U\xd5\x00:\xadW\x00\x00\x7f\x00\x00\x1dT\xd5\x00\x1a\xadW\xe0\x00\x7f\x00\x00\x1c\xa5\xd7\x00\x0e\xb7T\x1e\x00\x7f\x00\x00\x0fU\xdd\xc3\xfdOU\xf8\x00\x7f\x00\x00\x06\xaa\xa2\xe5V\xba\xa5\x80\x00\x7f\x00\x00\x03\xa9\xbe\xba\xaa\xb2W\x00\x00\x7f\x00\x00\x03U\xc1ZUj\xac\x00\x00\x7f\x10\x0c\x03\xab\xbfU\xaaj\xac\x00\x00\x7f\x00\x08\x03\xa5\xfb\xaaU\xaa\xa8\x00\x00\x7f\x00\x00\x03\xd5\xd4\xd5\xaar\x98\x00\x00\x7f\x00\x00\x03\x97UtU\xfdX\x1c\x00\x7f\x00\x00\x03\xa8\xaa{\x97\x92\xa8\x0c\x00\x7f\x00\x00\x03UUW\xf5UX\x00\x00\x7f\x00\x00\x07\xaa\xaa\xbd>\xaaL\x00\x00\x7f\x00\x00\x06>\x95YOS\xec\x00\x00\x7f\x00\x00\r\xff\xca\xba\xaa\xaf\xfa\x00\x00\x7f\x00\x00\x1f\x81\xf5Z\xab_\x0e\x00\x00\x7f\x00\x00\x1e\x00uIT\x9c\x03\x00\x00\x7f\x00\xc00\x00:\xaa\xaa\xb8\x00\x00\x00\x7f\x00\x00@\x00\x1a\xaa\xa2\x98\x00\x00\x04\x7f\x00\x00\x00\x00\tH\xfc\x98\x00\x00\x00\x7f\x00\x00\x00\x10\x0e\xab\xffp\x000\x00\x7f\x00\x00\x00\x00\x05O\x83P@\x10\x00\x7f\x00\x00\x00\x80\x06\xbe\x00\xd0 \x00\x00\x7f\x00\x04\x00\x00\x06\xb8\x00p\x00\x00\x00\x7f\x00\x10\x00\x00\x03p\x000\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xe0\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xc0\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
DOOR_CLOSE=b'BM>\x02\x00\x00\x00\x00\x00\x00>\x00\x00\x00(\x00\x00\x00@\x00\x00\x00@\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x02\x00\x00\xc4\x0e\x00\x00\xc4\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\x00\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x18\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x00\x08\x00\x00\x01\x80\x00\x00\x18\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x11\x8c\x00\x00\x10\x08\x00\x009\x9e\x00\x00\x10\x08\x00\x00y\x9e\x00\x00\x10\x08\x00\x001\x8c\x00\x00\x10\x08\x00\x00\x11\x88\x00\x00\x10\x08\x00\x00\x11\x88\x00\x00\x10\x08\x00\x00\x11\x88\x00\x00\x10\x08\x00\x001\x8c\x00\x00\x10\x08\x00\x00y\x9e\x00\x00\x10\x08\x00\x009\x9e\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x18\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x00\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x08\x00\x00\x01\x80\x00\x00\x10\x0f\xff\xff\xff\xff\xff\xff\xf0\x0f\xff\xff\xff\xff\xff\xff\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
DOOR_OPEN=b'BM>\x02\x00\x00\x00\x00\x00\x00>\x00\x00\x00(\x00\x00\x00@\x00\x00\x00@\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x02\x00\x00\xc4\x0e\x00\x00\xc4\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\x00\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xe0\x0f\xff\xff\xff\xff\xff\xff\xf0\x0f\xff\xff\xff\xff\xff\xff\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
DOOR_OPENING=b'BM>\x02\x00\x00\x00\x00\x00\x00>\x00\x00\x00(\x00\x00\x00@\x00\x00\x00@\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x02\x00\x00\xc4\x0e\x00\x00\xc4\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\x00\x08\xff\xff\xff\xff\xff\xff\x10\x08\x07\xff\xff\xff\xff\xe0\x10\x08\x00?\xff\xff\xfc\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x003\xff\xff\xcc\x00\x10\x08\x003\xff\xff\xcc\x00\x10\x08\x003\xff\xff\xcc\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x003\xff\xff\xcc\x00\x10\x08\x003\xff\xff\xcc\x00\x10\x08\x003\xff\xff\xcc\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x00\x00\x03\xff\xff\xc0\x00\x00\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00\x03\xff\xff\xc0\x00\x10\x08\x00?\xff\xff\xfc\x00\x10\x08\x07\xff\xff\xff\xff\xe0\x10\x08\xff\xff\xff\xff\xff\xff\x10\x0f\xff\xff\xff\xff\xff\xff\xf0\x0f\xff\xff\xff\xff\xff\xff\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Fire=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x7f\x00\x00\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x7f\x00\x00\x03\x00\x00\x0f\x80\x00\x00\x01\x80\x7f\x00\x00\x03\x80\x00\x0f\x80\x00\x00\x03\x80\x7f\x00\x00\x03\xc0\x00\x0f\xc0\x00\x00\x07\x80\x7f\x00\x00\x07\xe0\x00\x1f\xc0\x00\x00\x07\x80\x7f\x00\x00\x07\xf0\x00\x1f\xc0\x00\x00\x07\xc0\x7f\x00\x00\x0f\xf0\x00?\xc0\x00\x00\x03\xc0\x7f\x00\x00\x0f\xf0\x00\x7f\xc0\x00\x00\x03\xe0\x7f\x00\x00\x1f\xf0\x00\xff\xc0\x00\x00\x03\xe0\x7f\x00\x00\x1f\xf0\x01\xff\xc0\x00\x00\x03\xf0\x7f\x00\x00\x1f\xf0\x07\xff\xc0\x00\x00\x03\xf8\x7f\x00\x00\x1f\xe0\x07\xff\xc0\x00\x00\x03\xfc\x7f\x00\x00\x1f\xe0\x0f\xff\xc0\x00\x00\x03\xfc\x7f\x00\x00\x1f\xe0\x0f\xff\xc0|\x00\x07\xfc\x7f\x00\x00\x0f\xe0\x1f\xff\xc3\xfe\x00\x07\xfc\x7f\x00\x00\x07\xc0\x1f\xff\x87\xfc\x00\x0f\xfc\x7f\x00\x00\x01\xc1\x1f\xff\x8f\xf8\x00?\xfc\x7f\x00\x00\x00\xe3\xbf\xef\x9f\xf8\x00\xff\xfc\x7f\x00\x00\x007\xbf\xef\xdf\xf8\x01\xff\xf8\x7f\x00\x00\x00\x0f\xbf\xdf\xff\xf0\x03\xff\xf8\x7f\x00\x00\x00\x1f\xdf\xdf\xfe\xf0\x07\xff\xf0\x7f\x10\x00\x00\x1f\xff\xdf\xff\xf0\x07\xff\x80\x7f\x18\x00\x00\x1f\xff\xaf\xfd\xf0\x0f\x80\x00\x7f\x1c\x00\x04\x1f\xff\xbf\xfb\xe0\x08\x00\x00\x7f\x1e\x00\x1e\x1f\xff\xdf\xfb\xe0\x00\x00\x00\x7f\x1f\x00>\x1f\xff\xaf\xfb\xe0\x00\x00\x00\x7f\x1f\x80~\x1f\xff\xaf\xf7\xe0\x00\x00\x00\x7f\x1f\xc0\x7f\x1f\xff\xaf\xeb\xe0~\x00\x00\x7f\x1f\xf0\x7f\x1f\xff\xd7\xf7\xe1\xfe\x00\x00\x7f\x1f\xf0\xff\x9f\xff\xab\xeb\xe7\xfc\x00\x00\x7f\x0f\xf8\xff\x8f\xbf\xab\xd7\xef\xf8\x00\x00\x7f\x0f\xf8\xff\xcf\xcf\xd5\xd7\xff\xf8\x0e\x00\x7f\x0f\xf8\xff\xef\xf5\xaa\xab\xffp\x7f\x00\x7f\x07\xfc\xff\xff\xf5UW\xfd\xf1\xfe\x00\x7f\x07\xfc\x7f\xff\xf5J\xab\xfe\xe3\xfc\x00\x7f\x03\xfc\x7f\xff\xfa\xf5U\xfd\xe7\xf8\x00\x7f\x01\xfc\x7f\xff\xfe\x9dU\xf5\xef\xf0\x00\x7f\x00\xfc\x7f\xff\xfdF\xaa\xea\xef\xf0\x00\x7f\x00<?\xff\xfdCUu\xff\xe0\x00\x7f\x00\x01?\xbf\xf5CUU\xfd\xe0\x00\x7f\x00\x01?\xab\xd5AUU\xfd\xc0\x00\x7f\x00\x01\x9f\xd5U`\xaa\xaa\xfb\xc0\x00\x7f\x00\x03\xcf\xea\xaa\xa0\xaa\xaa\xf7\x80\x00\x7f\x00\x03\xcf\xd5]`UU\xeb\x80\x00\x7f\x00\x03\xe7\xea\xb5@j\xd5w\x80\x00\x7f\x00\x03\xfb\xea\xa6\xc0+\xaa\xef\x80\x00\x7f\x00\x03\xff\xea\xa3@jUO\x80\x00\x7f\x00\x03\xff\xf5B\xc0J\xaa\xbf\x80\x00\x7f\x00\x03\xff\xfa\xa2\x804\xd5O\x80\x00\x7f\x00\x01\xff\xfda\x80,\xaa\xbf\x80\x00\x7f\x00\x01\xfe\xfa\xa1\x00(\xd5_\x80\x00\x7f\x00\x01\xfe\xad \x00p\xaa\xbf\x80\x00\x7f\x00\x00\xff\xaa\xe0\x00@\xd7_\x80\x00\x7f\x00\x00\x7fU \x00\x00\xaa\xbf\x00\x00\x7f\x00\x00\x7f\xd5\xf0\x00\x01\xb2\xbf\x00\x00\x7f\x00\x00?\xd5\xb8\x00\x01b\xbf\x00\x00\x7f\x00\x00\x0f\xf5@\x00\x03\x82\xbe\x00\x00\x7f\x00\x00\x03\xfa\xa0\x00\x00\x05~\x00\x00\x7f\x00\x00\x00\xfa\xb0\x00\x00\x06\xfc\x00\x00\x7f\x00\x00\x00}P\x00\x00\x05x\x00\x00\x7f'
|
||||
Flowers=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x80\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xc0\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00?\xc3\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00?\xcf\xc0\x7f\x00\x00\x00\x00\x00\x00\x00\x0f\x7f\xdf\xc0\x7f\x00\x00\x00\x00\x00\x00\x00\x1f\xff\xdf\xe0\x7f\x00\x00\x00\x00\x00\x00\x00?\x7f\xff\xe0\x7f\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xdf\xc0\x7f\x00\x00\x0c\x00\x00\x00\x00\x7f\x7f\xff\x90\x7f\x00\x00\x1c\x00\x00\x00\x00\xff\x7f\xfe|\x7f\x00\x06\x1c\x00\x00\x00\x00\xff\x7f\xbc\xfe\x7f\x00\x07\x1c\x00\x00\x00\x00\xffw9\xfe\x7f\x01\xc7\x1c\x18\x00\x00\x00\xffR{\xfe\x7f\x01\xe3\x9c\x1c\x00\x00\x00\x7f\x0co\xfe\x7f\x00\xf3\x9c8\x00\x00\x00}\x7f\x0f\xfc\x7f\x10y\x8cp\x00\x00\x00~\xff\x9f\xf0\x7f<<\xccq\x80\x00\x0f\xbc\xff\xc7\x80\x7f?\x1c\xcc\xe7\xc0\x00\x1f\xcc\xff\xc0\x00\x7f\x1f\xceH\xcf\x80\x00?\xe0\xff\xdf\x00\x7f\x07\xe6I\x9e\x00\x00?\xfc\xff\xaf\xf8\x7f\x00\xf9\t<\x00\x00?\xfb\x7f7\xfe\x7f<\x1c"p\x00\x00?\xff\x00\x1f\xfe\x7f?\xc0\xd1\x87\xe0\x00?\xfe\x01\x9f\xff\x7f?\xfd\xb8?\x80\x00\x1f\xfc)\xcf\xff\x7f\x00\x01\xf9\xfc\x00\x00\x07\xf1g\xef\xff\x7f\x00\x01\xec\x00\x00\x00\x00\x03\xdf\xf7\xfe\x7f\x07\xf0\xf8\x00\x00\x00\x00\x0f\xd7\xf3\xfc\x7f\x1f\xc20\xff\xe0\x00\x00\x7f\xef\xf9\xf8\x7f?\x07\x0b?\xe0\x00\x03\xff\xef\xf8@\x7f<\ri\x80\xc0\x00\x03\xff\xef\xf8\x00\x7f\x00\x1fm\xc0\x00\x00\x03\xff\xcf\xf8\x00\x7f\x00?l\xe0\x00\x00\x03\xff\x8f\xf8\x00\x7f\x00~\xeep\x00\x00\x01\xff\x0f\xf8\x00\x7f\x01\xee\xeex\x00\x00\x00\xfc\x0f\xf0\x00\x7f\x03\xde\xef<\x00\x00\x00\x00\x07\xf0\x00\x7f\x03\x9c\xe7\x1c\x06\x00\x00\x00\x07\xe4\x00\x7f\x00\x1d\xf7\x00\xce\x00\x00\x00\x03\xcc\x00\x7f\x00=\xd7\x04f \x00\x00\x00\x04\x00\x7f\x00\x19\xd6\x07fp\x00\x00\x00\x06\x00\x7f\x00\x00\x80\x03$`\x00\x00\x00\x02\x00\x7f\x00\x00 9\x94\xcc\x00\x0f\x00\x03\x00\x7f\x00\x00 <\xd4\x9c\x00?\x80\x01\x00\x7f\x00\x00 \x0fEp\x1e\x7f\x80\x01\x00\x7f\x03\x00 0\x81@?\xbb\xb0\x01\x80\x7f\x03`@\x7f\x9c>\x1d\x7f\xb8\x00\x80\x7f\x00\xe0@\x00<\xf0\x1e\xef\xf8\x00\x80\x7f\x00x@\x07=\x00\x1f\xd7\xdc\x00\xc0\x7f\x000\xc0<H\xfe\x1fw\xfc\x00@\x7f\x00\x1c\x80x\xd3\x0e\x1d\xef\xf8\x00@\x7f\x00\x1c\x80\x01\xd5\x80\x1f\xab\xb8\x00`\x7f\x00\x0c\x80\x03\xd6\xc0=\xef\xe0\x00 \x7f\x00\x05\x80\x07\xf6`\x7f}\xe0\x00 \x7f\x00\x01\x00\r\xbb0\x7f\xbf\xe0\x000\x7f\x00\x01\x01\xc1\xbb\x00\x87\xff\xc0\x000\x7f\x00\x01\x03\x81\xb3\x00\x03\xbf\x80\x00\x10\x7f\x00\x01\x0f\xc0\x00\x00\x01\xdb\x80\x00\x10\x7f\x00\x03\x0f\xe0\x08\x00\x00<\x00\x00\x18\x7f\x00\x02\x1f\x00\x08\x00\x00\x0c\x00\x00\x18\x7f\x00\x02?\x00\x10\x00\x00\x0c\x00\x00\x18\x7f\x00\x02>\x00\x10\x00\x00\x04\x00\x00\x08\x7f\x00\x02p\x00\x10\x00\x00\x04\x00\x00\x08\x7f'
|
||||
Forest=b"P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00p\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x01\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00~\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00z\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x01\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x07\xff\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x0f\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\xff\xc0\x00\x00\x00\x00\x06\x00\x00\x7f\x00\x00\xfe\x00\x00\x00\x08\x00\x06\x00\x00\x7f\x00\x03\xff\x00\x00\x00\x0c\x89\x9d\x83\x00\x7f\x00\x0f\xff\x80\x00\x00\x07\x8d\x8b\x0e\x00\x7f\x00\x1f\xff\xc0\x00\x19a\xb0\x04\xc9\x80\x7f\x00?\xff\xf0\x00\x1b\x1aV\x1a\xb3\x90\x7f\x00\x7f\xff\xf0\x00\x06\xef\x84A\x14\x10\x7f\x00\xff\xff\xf8\x00\x1a`\xbb\x14\x8b\x10\x7f\x00\x01\xff\x04\x00P\x1b\x89d\xf4\x06\x7f\x00\x03\xff\x80\x00f\xe2\x91 d\x9e\x7f\x00\x0f\xff\xc0\x00\x018\xeb\xc7\xe0`\x7f\x00\x1f\xff\xf0\x00\xc4\xc1\xa8\xcc\xe1\xa8\x7f\x00?\xff\xf8\x04\xd6}\xb1\x15aL\x7f\x00\x7f\xff\xfe\x0e!/A\xe5`\xb0\x7f\x00\xff\xff\xff\x80\xd4'\x06 o0\x7f\x01\xfd\xff\xc1\xc35[\x06\xb0{\x00\x7f\x03\xe1\xff\xe0\x02\xb1\x13\xc1\xa0\xe10\x7f\x03\x87\xff\xf0\x01\xb0\x01\xe0\x03\xe6\xcc\x7f\x04\x1f\xff\xfc\x000\x03\xf8?\xc4Y\x7f\x00?\xff\xff\x80\x98\x07\xfc\xff\x81\x8b\xff\x00\x7f\xff\xff\xe3d\x1f\xfd\xfc\x01h\x7f\x01\xff\xff\xff\xc0\xe7\xfe?\xc0\x88L\x7f\x07\xff\xff\xfc\x0e\xa1\xf0\x0f\x84\x98\x0c\x7f\x1f\xf7\xff\xf0\x06X\xc0\x0f\x86\n\x00\x7f\x1f\xe7\xff\xf0\x03I\x80\x07\x81\x17\x00\x7f\x00\x07\xff\xf8\x03/@\x07\x81 0\x7f\x00\x0f\xff\xfc\x00\xb4@\x0f\x80\xcd\xe0\x7f\x00?\xff\xfe\x03\xe4\x80\x0f\x86\xc0(\x7f\x00\xff\xff\xff\x02c\x00?\x82\x87\xdc\x7f\x03\xff\xff\xff\x80\xc5\x07\xff\xfd\x8d@\x7f\x07\xe7\xff\xc7\xf0\x16?\xff\xff\xf9\xe0\x7f\x1c\x0f\xff\xe0x\x12\x7f\xfe\x0f\xf8\x80\x7f\x00?\xff\xf0\x00\x11\xff\xf8\x02\x84@\x7f\x00\x7f\xff\xfc\x00\x01\xff\xe0\x02D\xc0\x7f\x00\xff\xff\xfe\x00\x03\xff\x00\x02\xca\x80\x7f\x01\xff?\xff\x80\x07\xfe\x00\x00\x19p\x7f\x03\xfc;\xff\xe0\x07\xfc\x00\x00\x13 \x7f\x0f\xf08\xff\xf8\x0f\xf8\x00\x00\x02\xc0\x7f\x7f\x008\x0f\xff\x1f\xf8\x00\x00\x02\xc0\x7f\x00\x008\x00\x00\x1f\xf8\x00\x00\x00\x00\x7f\x00\x008\x00\x00?\xf8\x00\x00\x00\x00\x7f\x00\x008\x00\x0e\x7f\xf9\x00\x00\x00\x00\x7f\x00\x008\x00\xff\xff\xff\x80\x00\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x000\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f"
|
||||
Lightning=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xff\xf8\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xf0\x18\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xff\x90\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xff\xa0\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xff@\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xfe\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x07\xff\xfe\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x07\xff\xfd\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfb\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfa\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xe8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xf0\x00\x00\x00\x00\x7f\x00\x00\x00\x00?\xff\xa0\x00\x00\x00\x00\x7f\x00\x00\x00\x00?\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xff\xf8\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xff\x90\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xff\xb0\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xff`\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xfe\xc0\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xfc\x80\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xf9\x00\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xfa\x00\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xf4\x00\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xec\x00\x00\x00\x00\x7f\x00\x00\x00\x0f\xff\xff\xd8\x00\x00\x00\x00\x7f\x00\x00\x00\x0f\xff\xff\xf0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff \x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xfe\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x07\xff\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x07\xff\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xfe\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xfc\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xf8\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xf0\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xe0\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00?\xc0\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00?\xc0\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00?\x80\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00~\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xfc\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xf8\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x01\xf0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x01\xf0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x01\xe0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x03\x80\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Light_off=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xd5p\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x07J\xb8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1c\xb5\\\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1bEV\x00\x00\x00\x00\x7f\x00\x00\x00\x004\n\xab\x00\x00\x00\x00\x7f\x00\x00\x00\x00tUU\x00\x00\x00\x00\x7f\x00\x00\x00\x00h\xaa\xab\x80\x00\x00\x00\x7f\x00\x00\x00\x00\xd1UU\x80\x00\x00\x00\x7f\x00\x00\x00\x00\xd2\xaa\xaa\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\xa2\xaa\xaa\xc0\x00\x00\x00\x7f\x00\x00\x00\x01\xa5UU@\x00\x00\x00\x7f\x00\x00\x00\x01\xd2\xaa\xaa\xc0\x00\x00\x00\x7f\x00\x00\x00\x01\xa5UU@\x00\x00\x00\x7f\x00\x00\x00\x01\xaa\xaa\xaa\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\xd5UU\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\xd5UT\x80\x00\x00\x00\x7f\x00\x00\x00\x00\xd5UW\x80\x00\x00\x00\x7f\x00\x00\x00\x00j\xaa\xa9\x80\x00\x00\x00\x7f\x00\x00\x00\x00eUW\x00\x00\x00\x00\x7f\x00\x00\x00\x00=US\x00\x00\x00\x00\x7f\x00\x00\x00\x002\xaa\xae\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1dUV\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1a\xaa\xac\x00\x00\x00\x00\x7f\x00\x00\x00\x00\rU\\\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0e\xaa\xa8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x05UX\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x06\xaa\xb8\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x06\xaa\x90\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x06Up\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xaa\xb0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03U`\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xaa\xa0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03U`\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x7f\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x80\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x83\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00>\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Light_on=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\xc0\x00\x0c\x00\x02\x00\x00\x00\x7f\x00\x00\x00`\x00\x00\x00\x06\x00\x00\x00\x7f\x00\x00\x000\x00\x00\x00\x0c\x00\x00\x00\x7f\x00\x00\x00\x18\x00\x00\x00\x18\x00\x00\x00\x7f\x00\x00\x00\x0c\x00\x1e\x000\x00\x00\x00\x7f\x00\x00\x00\x06\x00\xff\xc0`\x00\x00\x00\x7f\x00\x00\x00\x02\x03\x80p\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x06\x00\x18\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x18\x00\x0c\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x100\x06\x00\x00\x00\x00\x7f\x00\x00\x00\x000\xe0\x03\x00\x00\x00\x00\x7f\x00\x00\x00\x00a\x80\x01\x00\x00\x00\x00\x7f\x00\x00\x00\x00B\x00\x01\x80\x00\x00\x00\x7f\x00\x00\x00\x00\xc6\x00\x00\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x84\x00\x00\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x8c\x00\x00\xc0\x00\x00\x00\x7f\x00\x00\x00\x01\x8c\x00\x00@\x00\x00\x00\x7f\x00\x00\x00\x01\x88\x00\x00@\x00\x00\x00\x7f\x00\x00\x00\x01\x80\x00\x00@\xfe\x00\x00\x7f\x00\x00\x7f\xc1\x80\x00\x00A\xfe\x00\x00\x7f\x00\x00\x00\x00\x80\x00\x00\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\xc0\x00\x00\x80\x00\x00\x00\x7f\x00\x00\x00\x00\xc0\x00\x00\x80\x00\x00\x00\x7f\x00\x00\x00\x00@\x00\x01\x80\x00\x00\x00\x7f\x00\x00\x00\x00`\x00\x01\x00\x00\x00\x00\x7f\x00\x00\x00\x00 \x00\x03\x00\x00\x00\x00\x7f\x00\x00\x00\x000\x00\x02\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x10\x00\x06\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x18\x00\x04\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x08\x00\x0c\x0c\x00\x00\x00\x7f\x00\x00\x00\x18\x0c\x00\x08\x06\x00\x00\x00\x7f\x00\x00\x000\x04\x00\x08\x03\x00\x00\x00\x7f\x00\x00\x00`\x04\x00\x18\x01\x80\x00\x00\x7f\x00\x00\x00\xc0\x06\x00\x10\x00\xc0\x00\x00\x7f\x00\x00\x01\x80\x06\x00\x10\x00`\x00\x00\x7f\x00\x00\x01\x00\x02\x000\x00 \x00\x00\x7f\x00\x00\x00\x00\x02\x00 \x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\x00 \x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\x00 \x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x7f\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x80\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x83\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00>\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Night=b'P4\n89 64\n\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfd\x7f\xff\xff\xff\xfe\x00\x7f\xff\xdf\xff\xff\xf7\xdf\xff\xff\xff\xe0\x00?\xff\xff\xff\xff\xef\xff\xff\xff\xff\x80\x01\xff\xff\xff\xff\x7f\xff\xef\xff\xff\xfe\x00\x07\xff\xff\xff\xff?\xdf\xff\xff\xff\xfc\x00\x0f\xff\xff\xff\xfe\x1f\xff\xff\xff\xff\xf8\x00?\xff\x87\xff\xfe?\xdf\xff\xff\xff\xf0\x00\x7f\xff\xcf\xff\xfe?\xff\xef\xff\xff\xe0\x00\xff\xff\xcf\xff\xff\xff\xef\xdf\xff\xff\xc0\x01\xff\xff\xff\xff\xff\xff\xfb\xbf\xff\xff\x80\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x00\x0f\xff\xff\xff\xfd\xff\xff\xff\xff\xff\xfe\x00\x0f\xff\xff\xff\xf9\xff\xff\xff\xff\xff\xfc\x00\x0f\xff\xff\xff\xe0?\xff\xcf\xff\xff\xfc\x00\x1f\xff\xff\xff\xe0?\xff\x87\xff\xff\xfc\x00\x1f\xff\xff\xff\xf0\x7f\xff\x8f\xff\xff\xfc\x00\x1f\xff\xff\xff\xf0\x7f\xff\xcf\xff\xff\xfc\x00\x1f\xff\xff\xff\xf2\x7f\xbf\xff\xff\xff\xf8\x00?\xff\xff\xff\xff\xff\xbf\xff\xff\xff\xf8\x00?\xfd\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x00\x1f\xff\xf5\xfb\xff\xff\xff\xf9\xff\xff\xfc\x00\x1f\xff\xee\xfb\xff\xff\xff\xff\xff\xff\xfc\x00\x1f\xff\xee\xff\xff\xff\xff\xff\xff\xff\xfc\x00\x1f\xff\xf5\xff\xff\xff\xff\xff\xff\xff\xfe\x00\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x07\xff\xff\xff\xff\xff\xff\xfd\xff\xff\xff\x80\x03\xff\xef\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x01\xff\xff\xfe\x7f\xff\xff\xff\xff\xff\xff\xe0\x00\xff\xff\xfe\x7f\xff\xff\xff\xff\xff\xff\xf0\x00\x7f\xff\xfc?\xff\xff\xff\xff\xff\xff\xf8\x00?\xff\xe0\x07\xff\xff\xff\xff\xff\xff\xfe\x00\x1f\xff\xc0\x03\xff\xff\xff\xff\xff\xff\xff\x00\x0f\xff\xe0\x07\xff\xff\xff\xbf\xff\xff\xff\xc0\x03\xff\xf0\x0f\xff\xf7\xff\x0f\xff\xff\xff\xf8\x00\x7f\xf8\x0f\xff\xff\xff\x1f\xff\xff\xff\xff\x83\xff\xf0\x0f\xff\xff\xff\x1f\xff\xff\xff\xff\xff\xff\xf0\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf3\xcf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x0f\xff\xff\xfd\x7f\xff\xf1\xff\xff\xff\xff\xf8\x1f\xff\xff\xfb\xbf\xff\xf9\xff\xff\xff\xff\xfc?\xff\xff\xfb\xbf?\xff\xff\xff\xff\xff\xfc\x1f\xff\xff\xfd\x7f?\xff\xff\xff\xff\xff\xfd\x9f\xff\xff\xff\xff?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
|
||||
Pirate=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00?\xff\xfe\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xff\xfb\x80\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xff\xf8\xc0\x00\x00\x00\x7f\x00\x00\x00\x03\xff\xff\xfe`\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\xb8\x00\x00\x00\x7f\x00\x00\x00\x0f\xff\xff\xff\xd8\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\xff\xff\xec\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\xff\xff\xee\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xf6\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xf6\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xff\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xff\x00\x00\x00\x7f\x00\x00\x00\x7f\xff\xff\xff\xff\x00\x00\x00\x7f\x00\x00\x00\x7f\xff\xff\xff\xff\x00\x00\x00\x7f\x00\x00\x00\x7f\xff\xff\xff\xff\x00\x00\x00\x7f\x00\x00\x00\x7f\xf9\xff\xe7\xff\x00\x00\x00\x7f\x00\x00\x00\x7f\xc0\x7f\x80\xff\x00\x00\x00\x7f\x00\x00\x00\x7f\xc0?\x00\xff\x00\x00\x00\x7f\x00\x00\x00\x7f\x80\x1e\x00\x7f\x00\x00\x00\x7f\x00\x00\x00\x7f\x80\x1e\x00\x7f\x00\x00\x00\x7f\x00\x00\x00\x7f\x80\x1e\x00\x7f\x00\x00\x00\x7f\x00\x00\x00\x7f\x80\x1e\x00\x7f\x00\x00\x00\x7f\x00\x00\x00?\x80\x1e\x00\x7f\x00\x00\x00\x7f\x00\x00\x00?\xc0?\x00\xff\x00\x00\x00\x7f\x00\x00\x00?\xe0s\x81\xfe\x00\x00\x00\x7f\x00\x00\x00\x1f\xf1\xf1\xe3\xfe\x00\x00\x00\x7f\x00\x00\x00\x1f\xff\xe1\xff\xfc\x00\x00\x00\x7f\x00\x00\x00\x0f\xff\xe0\xff\xf8\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xc0\xff\xe0\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xc0\x7f\xc0\x00\x00\x00\x7f\x00\x00\x00\x01\xff\xc0\x7f\xc0\x00\x00\x00\x7f\x00\x00\xf0\x00\xff\xff\xff\xc0\x00\x00\x00\x7f\x00\x00\xf0\x00\xff\xff\xff\x80\x00\xf0\x00\x7f\x00\x00\xf8\x00\x07\xff\xf8\x00\x01\xf0\x00\x7f\x00\x00\xf8\x00\x07\xff\xf8\x00\x03\xf0\x00\x7f\x00\x01\xff\x00\x07\xf7\xf8\x00\x07\xe0\x00\x7f\x00\x03\xff\xe0\x06s\x98\x00?\xf0\x00\x7f\x00\x03\xff\xfe\x00s\x98\x01\xff\xf8\x00\x7f\x00\x07\xff\xff\xc0!\x00\x1f\xff\xfc\x00\x7f\x00\x03\xf1\xff\xf8\x00\x01\xff\xf1\xfc\x00\x7f\x00\x03\xf0?\xff\x00\x0f\xff\x81\xf8\x00\x7f\x00\x01\xe0\x07\xff\xf0\x07\xfc\x01\xf8\x00\x7f\x00\x00\x00\x00\xff\xfe\x00`\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xfc\x00\x00\x00\x00\x7f\x00\x00p\x01\xc0\x7f\xff\xc0\x00\x00\x00\x7f\x00\x00\xfc\x1f\xf8\x0f\xff\xf8\x03\xe0\x00\x7f\x00\x01\xfd\xff\xfe\x01\xff\xff\x87\xf0\x00\x7f\x00\x03\xff\xff\xfe\x00?\xff\xff\xf0\x00\x7f\x00\x03\xff\xff\xf0\x00\x07\xff\xff\xf0\x00\x7f\x00\x01\xff\xff\x80\x00\x00\xff\xff\xf0\x00\x7f\x00\x00\xff\xfc\x00\x00\x00\x1f\xff\xf0\x00\x7f\x00\x00?\xc0\x00\x00\x00\x03\xff\xe0\x00\x7f\x00\x00?\x00\x00\x00\x00\x00\x7f\x80\x00\x7f\x00\x00?\x00\x00\x00\x00\x00\x1f\x00\x00\x7f\x00\x00?\x00\x00\x00\x00\x00\x1f\x00\x00\x7f\x00\x00\x1e\x00\x00\x00\x00\x00\x1f\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Snow=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\r\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x0c\xc0\x00\x02\x00\x7f\x00\x00\x00\x00\x00\x00\x13 \x00\x04\x00\x7f\x00\x00\x00\x00\x00\x00?\xf0\x00"`\x7f\x00\x10\x00\x00\x00\x00\x13`\x00\x1a\xc0\x7f\x00|\x00\x00\x00\x00\x04\x80\x00\x16\x00\x7f\x020\x80\x00\x01\x00\x0e\xc0\x00\x0f\x00\x7f\x02\xde\xc0\x00\x03\x00\x02\x80\x00\x1a\xc0\x7f\x0e\xba\xe0\x003\x18\x00\x00\x00$@\x7f\x07\xbb\xc0\x00;p\x00\x00\x00\x02\x00\x7f\t\xff0\x00\x1f\xe0\x00\x00\x00\x040\x7f\x03m\x80\x0c\x07\xc0@\x00\x00\x00x\x7f\x02\xee\xc0\x0c#\x10\xc0\x00\x00\x00p\x7f\r\xff\xb0\x0c{|\xc0\x00\x00\x00\x00\x7f\x07\xff\xc0l\xff\xfc\xcc\x00\x02\x00\x00\x7f\x0e\xba\xe0\xfc\xcf\xcc\xfc\x00\x1b`\x00\x7f\x02\xfe\x80<\xd3\xac\xf0\x00\x1f\xc0\x00\x7f\x02\x10\x80\x1f\xdbo\xf0\x00\x0f\xc0\x00\x7f\x00|\x00\x7f\xcf\xef\xfc\x08\x07\x00\x80\x7f\x00T\x00\xf1\xff\xff\x1e\x08\x03\x00\xc0\x7f\x00\x10\x00\x07\xff\xff\x80\x0c\x13 \x80\x7f\x00\x00\x00\x0f?\xf3\xe0<{y\xb0\x7f\x00\x00\x00\x1c\xfc\xfd\xe0<\x7f\xd9\xe0\x7f\x00\x00\x00\x0c\xfc~ ?g\x93\xe0\x7f\x00\x00\x00\x1e<\xf0\xe0\xff\xa77\xf8\x7f\x00\x80\x00\x07\xff\xfb\xc0\xe1\xe3>8\x7f\x00\x00\x00\xe3\xff\xff\x1e\x00\xfb|\x00\x7f\x02\xe0\x00\xff\xcf\xef\xbc\x03\xff\xff\x00\x7f\x01\x80\x00?\xdbo\xf0\x06\x0f\x83\x00\x7f\x00@\x00>\xd3,\xf8\x07\x9f\xc3\x00\x7f\x00\x80\x00|\xcf\xcc\xfc\x03\xff\xff\x00\x7f\x00\x00@\xec\xff\xfc\xce\x80\xf3<\x00\x7f\x00\x00\xc0\x0c\xfb|\xc0\xf9\xe3>x\x7f\x00\x00\xe0\x0c#\x10\xc0\x7f\'7\xf8\x7f\x00\x03\xf0\x0c\x07\xc0@>o\x91\xe0\x7f\x00\x03\xf0\x00\x1f\xe0\x00<{\xd9\xf0\x7f\x00\n\xd0\x00;\xf0\x00,{q\xa0\x7f\x00\x1e\xde\x0038\x00\x0c\x03\x00\xc0\x7f\x0e\x9c\xce|\x03\x00\x00\x08\x03\x00\xc0\x7f\x07\x87\xf8|\x01\x00\x00\x08\x07\x00\x80\x7f\x05\x8f\xdc|\x00\x00\x00\x00\x0f\xc0\x00\x7f\x03\xfe\xde\xf8\x00\x00\x00\x00\x1f\xe0\x00\x7f\x009\xf3\x10\x00\x00\x00\x00\x1b`\x00\x7f\x01\x9f\xff \x00\x00\x00\x00\x00\x00\x00\x7f\x00\xa7\xf9`\x00\x00\x00\x00\x10\x00\x00\x7f\x01\xff\xff\xe0\x00\x00\x00\x00\\\x00\x00\x7f\x01\xff\xff\xf0\x00\x00\x00\x008\x00\x00\x7f\x00\xa7\xfd`\x00\x00\x00\x02T\x80\x00\x7f\x01\x9d\xff \x00\x00\x00\x0e\xfe\xe0\x00\x7f\x033\xf3\x98\x00\x00\x00\x07\x9b\xc0\x00\x7f\x05\xde\xde\xe0\x00\x00\x00\r\xffp\x00\x7f\x07\x87\xd8|\x00\x02\x00\x03\x7f\x80\x00\x7f\x0f\xaf\xfd|\x00\x00\x00\x02\xee\xc0\x00\x7f\x02\x8c\xce0\x00\x12 \x03\xff\x80\x00\x7f\x00\x1e\xce\x00\x00\t\x80\r\xffp\x00\x7f\x00\x02\xc8\x00\x00\x07\x00\x07\xbb\xc0\x00\x7f\x00\x01\xf0\x00\x00\x0b\x80\x0e\xfe\xe0\x00\x7f\x00\x03\xd0\x00\x00\x19`\x02\xd4\x80\x00\x7f\x00\x01\xe0\x00\x00\x00\x00\x008\x80\x00\x7f\x00\x00\xe0\x00\x00\x03\x00\x00\\\x00\x00\x7f\x00\x00\xc0\x00\x00\x00\x00\x00\x10\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Target=b"P4\n89 64\n\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xfb\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x03\xf8\x08\x1f\xe0\x00\x00\x00\x7f\x00\x00\x00\x07\xe1\x00\x01\xf0\x00\x00\x00\x7f\x00\x00\x00\x1f\x10\x84 \xfc\x00\x00\x00\x7f\x00\x00\x00<\x00B\x10\x1e\x00\x00\x00\x7f\x00\x00\x00x\x84!\x08O\x00\x00\x00\x7f\x00\x00\x00\xe0B\x10\x84\x03\x80\x00\x00\x7f\x00\x00\x01\xe4!\x08B\x13\xc0\x00\x00\x7f\x00\x00\x03\x82\x10\x84!\x01\xe0\x00\x00\x7f\x00\x00\x07\xa1\x08B\x10\x84\xf0\x00\x00\x7f\x00\x00\x0e\x10\x84 \x08@x\x00\x00\x7f\x00\x00\x0e\x08B\x0c\x84!8\x00\x00\x7f\x00\x00\x1c\x84 \x08B\x10\x1c\x00\x00\x7f\x00\x008B\x10\xff\x01\x08N\x00\x00\x7f\x00\x008!\x03\xff\xe0\x84\x0e\x00\x00\x7f\x00\x00r\x10\x8f\x89\xf8B\x17\x00\x00\x7f\x00\x00q\x08\x1eU<!\x07\x00\x00\x7f\x00\x00p\x849UN\x10\x87\x00\x00\x7f\x00\x00\xe0BuUW\x08C\x80\x00\x7f\x00\x00\xe4 \xea\xaa\xab\x84#\x80\x00\x7f\x00\x00\xc2\x10\xca\xaa\xa9\x82\x03\x80\x00\x7f\x00\x01\xc1\t\xd5UU\xc1\t\xc0\x00\x7f\x00\x01\xc0\x81\x95R\xaa\xc0\x85\xc0\x00\x7f\x00\x01\xc8C\xaa\xadT\xe8A\xc0\x00\x7f\x00\x01\xc4#\xaa\xd2\xaa\xe0!\xc0\x00\x7f\x00\x01\xc2\x13U*\xaab\x11\xc0\x00\x7f\x00\x01\xc1\x03*\xc9Ui\x08\xc0\x00\x7f\x00\x07\xe0\x8f\xd5>\xaa\xf8\x83\xf0\x00\x7f\x00\x01\xc8\x0b\x15MUp@\xe0\x00\x7f\x00\x01\x84'j\xaa\x95d!\xc0\x00\x7f\x00\x01\xc2\x03\x95Ujb\x01\xc0\x00\x7f\x00\x01\xc1\x0b\xaa\xaa\x92\xe1\t\xc0\x00\x7f\x00\x01\xc0\x81\xaa\xb6n\xc0\x85\xc0\x00\x7f\x00\x01\xc8C\xd5I\x91\xc8A\xc0\x00\x7f\x00\x00\xe4 \xd56m\x84!\x80\x00\x7f\x00\x00\xe2\x10\xea\xc9\x93\x82\x13\x80\x00\x7f\x00\x00\xe1\x08u6w!\x03\x80\x00\x7f\x00\x00`\x849\xc9\x8e\x10\x87\x00\x00\x7f\x00\x00pB\x1e6<\x08G\x00\x00\x7f\x00\x00t!\x0f\x89\xf8\x84'\x00\x00\x7f\x00\x008\x10\x83\xff\xe0B\x0e\x00\x00\x7f\x00\x009\x08B\xff\x84!\x0e\x00\x00\x7f\x00\x00\x1c\x84 ,\x02\x10\x9c\x00\x00\x7f\x00\x00\x0eB\x10\x98!\x088\x00\x00\x7f\x00\x00\x0e\x01\x08B\x10\x848\x00\x00\x7f\x00\x00\x07\x90\x84!\x08Bp\x00\x00\x7f\x00\x00\x03\xc0B\x10\x84 \xe0\x00\x00\x7f\x00\x00\x01\xe4!\x08B\x13\xc0\x00\x00\x7f\x00\x00\x00\xe0\x10\x84!\x03\x80\x00\x00\x7f\x00\x00\x00y\x08B\x10\x8f\x00\x00\x00\x7f\x00\x00\x00<\x84!\x08\x1e\x00\x00\x00\x7f\x00\x00\x00\x1f\x02\x10\x84|\x00\x00\x00\x7f\x00\x00\x00\x07\xc1\x00A\xf0\x00\x00\x00\x7f\x00\x00\x00\x03\xf8\x08\x0f\xe0\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xeb\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f"
|
||||
14
mixly/boards/default/micropython/build/lib/oled128x64.py
Normal file
14
mixly/boards/default/micropython/build/lib/oled128x64.py
Normal file
@@ -0,0 +1,14 @@
|
||||
"""
|
||||
OLED Displays
|
||||
|
||||
Micropython library for the SSD1106_I2C OLED Displays
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
from ssd1106 import SSD1106_I2C
|
||||
|
||||
class OLED(SSD1106_I2C):
|
||||
"""A single matrix."""
|
||||
def __init__(self, i2c, width=128, height=64, address=0x3c, font_address=0x700000, types=0):
|
||||
super().__init__(width, height, i2c, address, l_offset=0 if types == 0 else -2)
|
||||
self.font(font_address)
|
||||
111
mixly/boards/default/micropython/build/lib/ollama.py
Normal file
111
mixly/boards/default/micropython/build/lib/ollama.py
Normal file
@@ -0,0 +1,111 @@
|
||||
import urequests
|
||||
import time
|
||||
import json
|
||||
|
||||
|
||||
class Ollama():
|
||||
def __init__(self, url="", model="", max_history_num=0):
|
||||
self._heads = {
|
||||
"Accept": "text/event-stream",
|
||||
# "Cache-Control": "no-cache",
|
||||
# "Connection": "keep-alive",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
self._url = url
|
||||
self._chat_url = "{}/api/chat".format(self._url)
|
||||
self._max_retries = 1
|
||||
self._max_history_num = max_history_num
|
||||
self._timeout = 10000
|
||||
self._messages = []
|
||||
self._data = {
|
||||
"stream": True,
|
||||
"model": model,
|
||||
"messages": self._messages
|
||||
}
|
||||
|
||||
def set_timeout(self, timeout):
|
||||
self._timeout = timeout
|
||||
|
||||
def set_max_retries(self, max_retries):
|
||||
self._max_retries = max_retries
|
||||
|
||||
def set_custom_url(self, url):
|
||||
self._url = url
|
||||
self._chat_url = "{}/api/chat".format(self._url)
|
||||
|
||||
def select_model(self, model_name):
|
||||
self._data["model"] = model_name
|
||||
|
||||
def set_max_history_num(self, num):
|
||||
self._max_history_num = num
|
||||
|
||||
def empty_history(self):
|
||||
self._messages = []
|
||||
|
||||
def add_history(self, role, content):
|
||||
self._messages.append({
|
||||
"role": role,
|
||||
"content": content
|
||||
})
|
||||
|
||||
def clear_user_history(self):
|
||||
if len(self._messages) < 2:
|
||||
return
|
||||
for i in range(1, len(self._messages)):
|
||||
del self._messages[i]
|
||||
|
||||
def _post(self, content_callback=None):
|
||||
response = None
|
||||
data = json.dumps(self._data).encode('utf-8')
|
||||
for i in range(0, self._max_retries):
|
||||
response = urequests.post(
|
||||
self._chat_url, headers=self._heads, data=data)
|
||||
if response.status_code == 200:
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
output = ""
|
||||
|
||||
if response.status_code != 200:
|
||||
output = response.text
|
||||
if content_callback:
|
||||
content_callback(output)
|
||||
return output
|
||||
|
||||
if not content_callback:
|
||||
output = json.loads(response.text)["message"]["content"]
|
||||
response.close()
|
||||
return output
|
||||
|
||||
try:
|
||||
while True:
|
||||
line = response.raw.readline()
|
||||
if line:
|
||||
line = line.decode('utf-8').strip()
|
||||
data = json.loads(line)
|
||||
if data["done"]:
|
||||
break
|
||||
content = data["message"]["content"]
|
||||
content_callback(content)
|
||||
output += content
|
||||
else:
|
||||
break
|
||||
finally:
|
||||
response.close()
|
||||
return output
|
||||
|
||||
def chat(self, message, content_callback=None):
|
||||
self.add_history("user", message)
|
||||
self._data["stream"] = bool(content_callback)
|
||||
self._heads["Accept"] = "text/event-stream" if content_callback else "application/json"
|
||||
content = self._post(content_callback)
|
||||
if self._max_history_num:
|
||||
self.add_history("assistant", content)
|
||||
messages_len = len(self._messages)
|
||||
history_num = 2 * self._max_history_num
|
||||
while history_num < messages_len:
|
||||
del self._messages[0]
|
||||
else:
|
||||
self.clear_user_history()
|
||||
|
||||
return content
|
||||
34
mixly/boards/default/micropython/build/lib/onenet.py
Normal file
34
mixly/boards/default/micropython/build/lib/onenet.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import ujson as json
|
||||
from umqtt import MQTTClient,str_len
|
||||
|
||||
def get_data_dict(d):
|
||||
result = {"datastreams":[]}
|
||||
for x in d:
|
||||
result["datastreams"].append({"id":x,"datapoints":[{"value":d[x]}]})
|
||||
return result
|
||||
|
||||
def pubData(value, state):
|
||||
value = get_data_dict(value)
|
||||
jdata = json.dumps(value)
|
||||
jlen = str_len(jdata)
|
||||
bdata = bytearray(jlen+3)
|
||||
bdata[0] = 1 #publish data in type of json
|
||||
bdata[1] = int(jlen / 256) # data lenght
|
||||
bdata[2] = jlen % 256 # data lenght
|
||||
bdata[3:jlen+4] = jdata.encode('ascii') # json data
|
||||
if state:
|
||||
print(value)
|
||||
#print(bdata)
|
||||
return bdata
|
||||
|
||||
def init_MQTT_client(sid, address, cid, api, topic, callback):
|
||||
client = MQTT_Client(sid, address, 6002, cid, api)
|
||||
client.set_callback(callback)
|
||||
client.connect()
|
||||
client.subscribe(bytes(topic, 'utf-8'))
|
||||
return client
|
||||
|
||||
#inherit
|
||||
class MQTT_Client(MQTTClient):
|
||||
def publish(self, msg, is_print=False, topic='$dp', retain=False, qos=0):
|
||||
super().publish('$dp',pubData(msg, is_print))
|
||||
53
mixly/boards/default/micropython/build/lib/openai.py
Normal file
53
mixly/boards/default/micropython/build/lib/openai.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import urequests
|
||||
import time
|
||||
import json
|
||||
import ollama
|
||||
|
||||
|
||||
class OpenAI(ollama.Ollama):
|
||||
def __init__(self, url="", api_key="", model="", max_history_num=0, max_tokens=1024):
|
||||
super().__init__(url, model, max_history_num)
|
||||
self._heads["Authorization"] = "Bearer {}".format(api_key)
|
||||
self._data["max_tokens"] = max_tokens
|
||||
self._chat_url = "{}/chat/completions".format(self._url)
|
||||
|
||||
def _post(self, content_callback=None):
|
||||
response = None
|
||||
data = json.dumps(self._data).encode('utf-8')
|
||||
for i in range(0, self._max_retries):
|
||||
response = urequests.post(
|
||||
self._chat_url, headers=self._heads, data=data)
|
||||
if response.status_code == 200:
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
output = ""
|
||||
|
||||
if response.status_code != 200:
|
||||
output = response.text
|
||||
if content_callback:
|
||||
content_callback(output)
|
||||
return output
|
||||
|
||||
if not content_callback:
|
||||
output = json.loads(response.text)[
|
||||
"choices"][0]["message"]["content"]
|
||||
response.close()
|
||||
return output
|
||||
|
||||
try:
|
||||
while True:
|
||||
line = response.raw.readline()
|
||||
if line[:5] != b"data:":
|
||||
continue
|
||||
if line[-7:-1] == b"[DONE]":
|
||||
break
|
||||
line = line[6:-1]
|
||||
line = line.decode('utf-8').strip()
|
||||
data = json.loads(line)
|
||||
content = data["choices"][0]["delta"]["content"]
|
||||
content_callback(content)
|
||||
output += content
|
||||
finally:
|
||||
response.close()
|
||||
return output
|
||||
126
mixly/boards/default/micropython/build/lib/pe_g1.py
Normal file
126
mixly/boards/default/micropython/build/lib/pe_g1.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""
|
||||
Micropython library for
|
||||
PE_G1 (Motor*5*2 & Servo*4)
|
||||
MDB (Motor*4*2 & Servo*6)
|
||||
===============================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
from time import sleep_ms
|
||||
from micropython import const
|
||||
|
||||
_PE_GX_ADDRESS = const(0x25)
|
||||
_PE_GX_ID = const(0x00)
|
||||
_PE_GX_VBAT = const(0x01)
|
||||
_PE_GX_MOTOR = const(0x03)
|
||||
|
||||
class PE_G1:
|
||||
def __init__(self, i2c_bus, addr=_PE_GX_ADDRESS):
|
||||
self._i2c = i2c_bus
|
||||
self._addr = addr
|
||||
sleep_ms(500)
|
||||
if self._rreg(_PE_GX_ID) == 0x25:
|
||||
self._PE_GX_SERVO = 0x0D
|
||||
self._type = 1 #PE_G1
|
||||
elif self._rreg(_PE_GX_ID) == 0x26:
|
||||
self._PE_GX_SERVO = 0x0B
|
||||
self._type = 2 #MDB
|
||||
else:
|
||||
raise AttributeError("Cannot find a PE_G1 or MDB")
|
||||
self.reset()
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
try:
|
||||
self._i2c.writeto_mem(self._addr, reg, val.to_bytes(1, 'little'))
|
||||
except:
|
||||
return 0
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
try:
|
||||
self._i2c.writeto(self._addr, reg.to_bytes(1, 'little'))
|
||||
return self._i2c.readfrom(self._addr, nbytes)[0] if nbytes <= 1 else self._i2c.readfrom(self._addr, nbytes)
|
||||
except:
|
||||
return 0
|
||||
|
||||
def reset(self):
|
||||
"""Reset all registers to default state"""
|
||||
if self._type == 1:
|
||||
self._i2c.writeto_mem(self._addr, _PE_GX_MOTOR, bytes(18))
|
||||
if self._type == 2:
|
||||
self._i2c.writeto_mem(self._addr, _PE_GX_MOTOR, bytes(20))
|
||||
|
||||
def read_bat(self, ratio=1):
|
||||
'''Read battery power'''
|
||||
vbat = self._rreg(_PE_GX_VBAT) << 2 | self._rreg(_PE_GX_VBAT+1) >> 6
|
||||
if self._type == 1:
|
||||
return round(vbat * ratio * 0.00968, 2)
|
||||
if self._type == 2:
|
||||
return round(vbat * ratio * 0.01398, 2)
|
||||
|
||||
def m_pwm(self, index, duty=None):
|
||||
"""Motor PWM duty cycle data register"""
|
||||
if self._type == 1: # Motor*5*2
|
||||
if not 0 <= index <= 9:
|
||||
raise ValueError("Motor port must be a number in the range: 0~4")
|
||||
if self._type == 2: # Motor*4*2
|
||||
if not 0 <= index <= 7:
|
||||
raise ValueError("Motor port must be a number in the range: 0~3")
|
||||
if duty is None:
|
||||
return self._rreg(_PE_GX_MOTOR + index)
|
||||
else:
|
||||
if not 0 <= duty <= 255:
|
||||
raise ValueError("Duty must be a number in the range: 0~255")
|
||||
self._wreg(_PE_GX_MOTOR + index, duty)
|
||||
|
||||
def s_pwm(self, index, duty=None):
|
||||
"""Servo PWM duty cycle data register"""
|
||||
if self._type == 1: # Servo*4
|
||||
if not 0 <= index <= 3:
|
||||
raise ValueError("Servo port must be a number in the range: 0~3")
|
||||
if self._type == 2: # Servo*6
|
||||
if not 0 <= index <= 5:
|
||||
raise ValueError("Servo port must be a number in the range: 0~5")
|
||||
if duty is None:
|
||||
return self._rreg(self._PE_GX_SERVO + index * 2) << 8 | self._rreg(self._PE_GX_SERVO + index * 2 + 1)
|
||||
else:
|
||||
if not 0 <= duty <= 4095:
|
||||
raise ValueError("Duty must be a number in the range: 0~4095")
|
||||
self._wreg(self._PE_GX_SERVO + index * 2,duty >> 8)
|
||||
self._wreg(self._PE_GX_SERVO + index * 2 + 1,duty & 0xff)
|
||||
|
||||
def motor(self, index, action="NC", speed=0):
|
||||
if not 0 <= speed <= 100:
|
||||
raise ValueError("Speed parameters must be a number in the range: 0~100")
|
||||
if action == "N":
|
||||
self.m_pwm(index * 2, 0)
|
||||
self.m_pwm(index * 2 + 1, 0)
|
||||
elif action == "P":
|
||||
self.m_pwm(index * 2, 255)
|
||||
self.m_pwm(index * 2 + 1, 255)
|
||||
elif action == "CW":
|
||||
self.m_pwm(index * 2, 0)
|
||||
self.m_pwm(index * 2 + 1, speed * 255 // 100)
|
||||
elif action == "CCW":
|
||||
self.m_pwm(index * 2, speed * 255 // 100)
|
||||
self.m_pwm(index * 2 + 1, 0)
|
||||
elif action == "NC":
|
||||
return round(self.m_pwm(index * 2) * 100 / 255), round(self.m_pwm(index * 2 + 1) * 100 / 255)
|
||||
else:
|
||||
raise ValueError('Invalid input, valid are "N","P","CW","CCW"')
|
||||
|
||||
def servo180(self, index, angle=None):
|
||||
if angle is None:
|
||||
return round((self.s_pwm(index) - 102.375) * 180 / 409.5)
|
||||
else:
|
||||
if not 0 <= angle <= 180:
|
||||
raise ValueError("Servo(180) angle must be a number in the range: 0~180")
|
||||
self.s_pwm(index,round(102.375 + 409.5 / 180 * angle))
|
||||
|
||||
def servo360(self, index, speed=None):
|
||||
if speed is None:
|
||||
return round((self.s_pwm(index) - 102.375) * 200 / 409.5 - 100)
|
||||
else:
|
||||
if not -100 <= speed <= 100:
|
||||
raise ValueError("Servo(360) speed must be a number in the range: -100~100")
|
||||
self.s_pwm(index,round(102.375 + 409.5 / 200 * (speed + 100)))
|
||||
41
mixly/boards/default/micropython/build/lib/pm2_5.py
Normal file
41
mixly/boards/default/micropython/build/lib/pm2_5.py
Normal file
@@ -0,0 +1,41 @@
|
||||
"""
|
||||
PM2.5
|
||||
|
||||
Micropython library for the PM2.5(UART)
|
||||
=======================================================
|
||||
#Preliminary composition 20220908
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
|
||||
class PM2_5:
|
||||
def __init__(self, uart):
|
||||
self._uart=uart
|
||||
self._uart.init(baudrate=9600)
|
||||
self._pm=(0,0)
|
||||
self._flag=False
|
||||
if not self._chip_id():
|
||||
raise AttributeError("Cannot find a PM2.5")
|
||||
|
||||
def _rreg(self):
|
||||
'''Read data'''
|
||||
if self._uart.any():
|
||||
eec=0
|
||||
buf=self._uart.read(7)
|
||||
for i in buf[1:5]:
|
||||
eec+=i
|
||||
if (eec & 0xff) == buf[5] and buf[0] == 0xAA and buf[6] == 0xFF:
|
||||
self._pm=(buf[1] << 8 | buf[2] , buf[3] << 8 | buf[4] )
|
||||
return True
|
||||
|
||||
def _chip_id(self):
|
||||
for _ in range(5):
|
||||
if self._rreg():
|
||||
return True
|
||||
time.sleep(1)
|
||||
return False
|
||||
|
||||
def concentration(self):
|
||||
self._rreg()
|
||||
return self._pm
|
||||
@@ -0,0 +1,29 @@
|
||||
#Take the picture bytes in progres_picture.py
|
||||
#--dahanzimin From the Mixly Team
|
||||
|
||||
Bar_0=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1ca\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x16\xd2\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x002\xd5\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x002w@\x00\x00\x00\x7f\x00\x00\x00\x00\x002\x0b@\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x19\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Bar_1=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x07\x1ea\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x05\x90\xd2\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x9c\xd5\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x01\x86w@\x00\x00\x00\x7f\x00\x00\x00\x00\x03\x02\x0b@\x00\x00\x00\x7f\x00\x00\x00\x00\x07\xbe\x19\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xea\xaa\xaa\xaa\xc0\x00\x00\x00\x00\x00\x00\xff\xd5RIU\x80\x00\x00\x00\x00\x00\x00\xff\xea\xad\xb6\xab\x00\x00\x00\x00\x00\x00\x00\xff\xd5RIV\x00\x00\x00\x00\x00\x00\x00\xff\xea\xad\xb6\xac\x00\x00\x00\x00\x00\x00\x00\xff\xd5RIX\x00\x00\x00\x00\x00\x00\x00\xff\xd5m\xb6\xb0\x00\x00\x00\x00\x00\x00\x00\xff\xea\x92I`\x00\x00\x00\x00\x00\x00\x00\xff\xd5m\xb6\xc0\x00\x00\x00\x00\x00\x00\x00\xff\xca\x92I\x80\x00\x00\x00\x00\x00\x00\x00\xff\xfbm\xb7\x00\x00\x00\x00\x00\x00\x00\x01\xff\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Bar_2=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x07\x9ca\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x04\x16\xd2\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x072\xd5\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xb2w@\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xb2\x0b@\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\x9e\x19\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xea\xaa\xaa\xaa\xaa\xaa\xac\x00\x00\x00\x00\xff\xd5$\x92I$\x95X\x00\x00\x00\x00\xff\xea\xdbm\xb6\xdbj\xb0\x00\x00\x00\x00\xff\xd5$\x92I$\x95`\x00\x00\x00\x00\xff\xd6\xdbm\xb6\xdbj\xc0\x00\x00\x00\x00\xff\xe9$\x92I$\x95\x80\x00\x00\x00\x00\xff\xd6\xdbm\xb6\xdbk\x00\x00\x00\x00\x00\xff\xc9$\x92I$\x96\x00\x00\x00\x00\x00\xff\xf6\xdbm\xb6\xdbl\x00\x00\x00\x00\x00\xff\xc9$\x92I$\x98\x00\x00\x00\x00\x00\xff\xf6\xdbm\xb6\xdbp\x00\x00\x00\x00\x01\xff\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Bar_3=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0f\x9ea\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\x90\xd2\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\x9c\xd5\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x03\x06w@\x00\x00\x00\x7f\x00\x00\x00\x00\x02\x02\x0b@\x00\x00\x00\x7f\x00\x00\x00\x00\x06>\x19\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd5UUUUUUUU\x80\x00\xff\xd5RI$\x92I$\x92\xab\x00\x00\xff\xea\xad\xb6\xdbm\xb6\xdbmV\x00\x00\xff\xd5RI$\x92I$\x92\xac\x00\x00\xff\xea\xad\xb6\xdbm\xb6\xdbmX\x00\x00\xff\xd5RI$\x92I$\x92\xb0\x00\x00\xff\xd5m\xb6\xdbm\xb6\xdbm`\x00\x00\xff\xea\x92I$\x92I$\x92\xc0\x00\x00\xff\xd5m\xb6\xdbm\xb6\xdbm\x80\x00\x00\xff\xca\x92I$\x92I$\x93\x00\x00\x00\xff\xfbm\xb6\xdbm\xb6\xdbn\x00\x00\x01\xff\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Bar_4=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x87\x1ca\x00\x00\x00\x00\x7f\x00\x00\x00\x01\xc5\x96\xd2\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xcc\xb2\xd5\x80\x00\x00\x00\x7f\x00\x00\x00\x00\xcc\xb2w@\x00\x00\x00\x7f\x00\x00\x00\x00\xcc\xb2\x0b@\x00\x00\x00\x7f\x00\x00\x00\x01\xe7\x9e\x19\xc0\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd5UUUUUUUUUU\xff\xd5$\x92I$\x92I$\x92I*\xff\xea\xdbm\xb6\xdbm\xb6\xdbm\xb6\xd5\xff\xd5$\x92I$\x92I$\x92I+\xff\xd6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xd5\xff\xe9$\x92I$\x92I$\x92I+\xff\xd6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xd5\xff\xc9$\x92I$\x92I$\x92I+\xff\xf6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xd5\xff\xc9$\x92I$\x92I$\x92I%\xff\xf6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdb\xff\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Dial_0=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00m\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xcc\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x07\xf8\x0c\x07\xf0\x00\x00\x00\x7f\x00\x00\x00\x1f\x80\x01\x00\xfc\x00\x00\x00\x7f\x00\x00\x00<\x00\x00\x00\x1f\x00\x00\x00\x7f\x00\x00\x00\xf0\x00\x00\x00\x07\xc0\x00\x00\x7f\x00\x00\x01\xe0\x00\x00\x00\x11\xe0\x00\x00\x7f\x00\x00\x07\x80\x00\x00\x00\x00p\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\x00\x018\x00\x00\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x1e\x00\x00\x7f\x00\x039\x00\x00\x00\x00\x00\x0f \x00\x7f\x00\x01\xb0\x00\x00\x00\x00\x00\x07`\x00\x7f\x00\x00\xc0\x00\x00\x00\x00\x00\x02\xc0\x00\x7f\x00\x00`\x00\x00\x00\x00\x00\x01\x80\x00\x7f\x00\x01\xa0\x00\x00\x00\x00\x00\x03`\x00\x7f\x00\x03\x80\x00\x00\x00\x00\x00\x00p\x00\x7f\x00\x07 \x00\x00\x00\x00\x00\x000\x00\x7f\x00\x06\x00\x00\x00\x00\x00\x00\x00\xb8\x00\x7f\x00\x0e\x80\x00\x00\x00\x00\x00\x00\x1c\x00\x7f\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x7f\x00\x19\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x7f\x008\x00\x00\x00\x00\x00\x00\x00\x06\x00\x7f\x002\x00\x00\x00\x00\x00\x00\x00\x06\x00\x7f\x000\x00\x00\x00\x00\x00\x00\x00\x17\x00\x7f\x00t\x00\x00\x00\x00\x00\x00\x00\x03\x00\x7f\x00`\x00\x00\x00\x00\x00\x00\x00\x03\x80\x7f\x00`\x00\x00\x00\x00\x00\x00\x00\x01\x80\x7f\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x01\x80\x7f\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x01\x80\x7f\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x01\xc0\x7f\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x7f\x01\xc0\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x01\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x0c\x00\x00\x00\x00\xc0\x7f\x01\x90\x00\x00\x00w@\x00\x00\x02\xc0\x7f\x00\x80\x00?\xff\xf9\x00\x00\x00\x00@\x7f\x07\xe1\x7f\xff\xff\xfd\xa0\x00\x00\x0b\xf8\x7f\x0f\xf0\xff\xff\xff\xfc\x80\x00\x00\x03\xf8\x7f\x00\x00\x00?\xff\xfd\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xfb\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Dial_1=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00m\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xcc\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x07\xf8\x0c\x07\xf0\x00\x00\x00\x7f\x00\x00\x00\x1f\x80\x01\x00\xfc\x00\x00\x00\x7f\x00\x00\x00<\x00\x00\x00\x1f\x00\x00\x00\x7f\x00\x00\x00\xf0\x00\x00\x00\x07\xc0\x00\x00\x7f\x00\x00\x01\xe0\x00\x00\x00\x11\xe0\x00\x00\x7f\x00\x00\x07\x80\x00\x00\x00\x00p\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\x00\x018\x00\x00\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x1e\x00\x00\x7f\x00\x039\x00\x00\x00\x00\x00\x0f \x00\x7f\x00\x01\xb0\x00\x00\x00\x00\x00\x07`\x00\x7f\x00\x00\xc0\x00\x00\x00\x00\x00\x02\xc0\x00\x7f\x00\x00`\x00\x00\x00\x00\x00\x01\x80\x00\x7f\x00\x01\xa0\x00\x00\x00\x00\x00\x03`\x00\x7f\x00\x03\x88\x00\x00\x00\x00\x00\x00p\x00\x7f\x00\x07 \x00\x00\x00\x00\x00\x000\x00\x7f\x00\x06\x02\x80\x00\x00\x00\x00\x00\xb8\x00\x7f\x00\x0e\x83\x00\x00\x00\x00\x00\x00\x1c\x00\x7f\x00\x1c\x01\x80\x00\x00\x00\x00\x00\x1c\x00\x7f\x00\x19\x00\xc0\x00\x00\x00\x00\x00\x0e\x00\x7f\x008\x00`\x00\x00\x00\x00\x00\x06\x00\x7f\x002\x010\x00\x00\x00\x00\x00\x06\x00\x7f\x000\x00\x1c\x80\x00\x00\x00\x00\x17\x00\x7f\x00t\x00N@\x00\x00\x00\x00\x03\x00\x7f\x00`\x00\x0f \x00\x00\x00\x00\x03\x80\x7f\x00`\x00\x17\x80\x00\x00\x00\x00\x01\x80\x7f\x00\xe0\x00\x03\xc0\x00\x00\x00\x00\x01\x80\x7f\x00\xc0\x00\x05\xf0\x00\x00\x00\x00\x01\x80\x7f\x00\xc0\x00\x00\xf8\x00\x00\x00\x00\x01\xc0\x7f\x00\xc0\x00\x00|\x00\x00\x00\x00\x00\xc0\x7f\x00\xc0\x00\x00>@\x00\x00\x00\x00\xc0\x7f\x01\xc0\x00\x00\x1f\x00\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x0f\xd0\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x0f\xe0\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x07\xf1\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x13\xfc\x00\x00\x00\x00\xc0\x7f\x01\x90\x00\x00\x01\xff@\x00\x00\x02\xc0\x7f\x00\x80\x00\x00\x04\xf9\x00\x00\x00\x00@\x7f\x07\xe4\x00\x00\x02}\xa0\x00\x00\x0b\xf8\x7f\x0f\xf0\x00\x00\x00\xfc\x80\x00\x00\x03\xf8\x7f\x00\x00\x00\x00\x00A\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Dial_2=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00m\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xcc\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x07\xf8\x0c\x07\xf0\x00\x00\x00\x7f\x00\x00\x00\x1f\x80\x01\x00\xfc\x00\x00\x00\x7f\x00\x00\x00<\x00\x02\x00\x1f\x00\x00\x00\x7f\x00\x00\x00\xf0\x00\x00\x00\x07\xc0\x00\x00\x7f\x00\x00\x01\xe0\x00\x08\x00\x11\xe0\x00\x00\x7f\x00\x00\x07\x80\x00\x00\x00\x00p\x00\x00\x7f\x00\x00\x0f\x00\x00$\x00\x018\x00\x00\x7f\x00\x00\x1c\x00\x00\x0c\x00\x00\x1e\x00\x00\x7f\x00\x039\x00\x00\x0c\x00\x00\x0f \x00\x7f\x00\x01\xb0\x00\x00\x0c\x00\x00\x07`\x00\x7f\x00\x00\xc0\x00\x00\x0c\x00\x00\x02\xc0\x00\x7f\x00\x00`\x00\x00\x0c\x00\x00\x01\x80\x00\x7f\x00\x01\xa0\x00\x00\x0c\x00\x00\x03`\x00\x7f\x00\x03\x80\x00\x00\x0c\x00\x00\x00p\x00\x7f\x00\x07 \x00\x00\x0c\x00\x00\x000\x00\x7f\x00\x06\x00\x00\x00\x0c\x00\x00\x00\xb8\x00\x7f\x00\x0e\x80\x00\x00\x0c\x00\x00\x00\x1c\x00\x7f\x00\x1c\x00\x00\x00N\x00\x00\x00\x1c\x00\x7f\x00\x19\x00\x00\x00\x1e\x80\x00\x00\x0e\x00\x7f\x008\x00\x00\x00\x1e\x00\x00\x00\x06\x00\x7f\x002\x00\x00\x00\x1e\x00\x00\x00\x06\x00\x7f\x000\x00\x00\x00\x1e\x00\x00\x00\x17\x00\x7f\x00t\x00\x00\x00\x1e\x00\x00\x00\x03\x00\x7f\x00`\x00\x00\x00\x1e\x00\x00\x00\x03\x80\x7f\x00`\x00\x00\x00\x1e\x00\x00\x00\x01\x80\x7f\x00\xe0\x00\x00\x00\x1e\x00\x00\x00\x01\x80\x7f\x00\xc0\x00\x00\x00\x1e\x00\x00\x00\x01\x80\x7f\x00\xc0\x00\x00\x00\x1e\x00\x00\x00\x01\xc0\x7f\x00\xc0\x00\x00\x00\x1e\x00\x00\x00\x00\xc0\x7f\x00\xc0\x00\x00\x00?\x00\x00\x00\x00\xc0\x7f\x01\xc0\x00\x00\x00?\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00?\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00?\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00?\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00?\x00\x00\x00\x00\xc0\x7f\x01\x90\x00\x00\x00?\x00\x00\x00\x02\xc0\x7f\x00\x80\x00\x00\x01\x7f\x00\x00\x00\x00@\x7f\x07\xe4\x00\x00\x00\x7f\xa0\x00\x00\x0b\xf8\x7f\x0f\xf0\x00\x00\x00\xde\x80\x00\x00\x03\xf8\x7f\x00\x00\x00\x00\x00A\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Dial_3=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00m\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xcc\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x07\xf8\x0c\x07\xf0\x00\x00\x00\x7f\x00\x00\x00\x1f\x80\x01\x00\xfc\x00\x00\x00\x7f\x00\x00\x00<\x00\x00\x00\x1f\x00\x00\x00\x7f\x00\x00\x00\xf0\x00\x00\x00\x07\xc0\x00\x00\x7f\x00\x00\x01\xe0\x00\x00\x00\x11\xe0\x00\x00\x7f\x00\x00\x07\x80\x00\x00\x00\x00p\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\x00\x018\x00\x00\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x1e\x00\x00\x7f\x00\x039\x00\x00\x00\x00\x00\x0f \x00\x7f\x00\x01\xb0\x00\x00\x00\x00\x00\x07`\x00\x7f\x00\x00\xc0\x00\x00\x00\x00\x00\x02\xc0\x00\x7f\x00\x00`\x00\x00\x00\x00\x00\x01\x80\x00\x7f\x00\x01\xa0\x00\x00\x00\x00\x00\x0b`\x00\x7f\x00\x03\x80\x00\x00\x00\x00\x00\x00p\x00\x7f\x00\x07 \x00\x00\x00\x00\x00\x000\x00\x7f\x00\x06\x00\x00\x00\x00\x00\x00\x10\xb8\x00\x7f\x00\x0e\x80\x00\x00\x00\x00\x00 \x1c\x00\x7f\x00\x1c\x00\x00\x00\x00\x00\x02H\x1c\x00\x7f\x00\x19\x00\x00\x00\x00\x00\x00\xd0\x0e\x00\x7f\x008\x00\x00\x00\x00\x00\x03\x80\x06\x00\x7f\x002\x00\x00\x00\x00\x00\x07\x00\x06\x00\x7f\x000\x00\x00\x00\x00\x00N\x00\x17\x00\x7f\x00t\x00\x00\x00\x00\x00\x1c\x00\x03\x00\x7f\x00`\x00\x00\x00\x00\x008\x00\x03\x80\x7f\x00`\x00\x00\x00\x00\x00\xf0\x00\x01\x80\x7f\x00\xe0\x00\x00\x00\x00\t\xe4\x00\x01\x80\x7f\x00\xc0\x00\x00\x00\x00\x03\xc0\x00\x01\x80\x7f\x00\xc0\x00\x00\x00\x00\x07\xd0\x00\x01\xc0\x7f\x00\xc0\x00\x00\x00\x00\x1f\x80\x00\x00\xc0\x7f\x00\xc0\x00\x00\x00\x00?\x00\x00\x00\xc0\x7f\x01\xc0\x00\x00\x00\x00~\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x04\xfc\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x01\xf8\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x03\xf2\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x0f\xe0\x00\x00\x00\xc0\x7f\x01\x90\x00\x00\x00?\xc0\x00\x00\x02\xc0\x7f\x00\x80\x00\x00\x01o\xd0\x00\x00\x00@\x7f\x07\xe4\x00\x00\x00O\x80\x00\x00\x0b\xf8\x7f\x0f\xf0\x00\x00\x00\xcf\x80\x00\x00\x03\xf8\x7f\x00\x00\x00\x00\x00a\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Dial_4=b"P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00m\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xff\xcc\xff\xc0\x00\x00\x00\x7f\x00\x00\x00\x07\xf8\x0c\x07\xf0\x00\x00\x00\x7f\x00\x00\x00\x1f\x80\x01\x00\xfc\x00\x00\x00\x7f\x00\x00\x00<\x00\x00\x00\x1f\x00\x00\x00\x7f\x00\x00\x00\xf0\x00\x00\x00\x07\xc0\x00\x00\x7f\x00\x00\x01\xe0\x00\x00\x00\x11\xe0\x00\x00\x7f\x00\x00\x07\x80\x00\x00\x00\x00p\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\x00\x018\x00\x00\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x1e\x00\x00\x7f\x00\x039\x00\x00\x00\x00\x00\x0f \x00\x7f\x00\x01\xb0\x00\x00\x00\x00\x00\x07`\x00\x7f\x00\x00\xc0\x00\x00\x00\x00\x00\x02\xc0\x00\x7f\x00\x00`\x00\x00\x00\x00\x00\x01\x80\x00\x7f\x00\x01\xa0\x00\x00\x00\x00\x00\x03`\x00\x7f\x00\x03\x80\x00\x00\x00\x00\x00\x00p\x00\x7f\x00\x07 \x00\x00\x00\x00\x00\x000\x00\x7f\x00\x06\x00\x00\x00\x00\x00\x00\x00\xb8\x00\x7f\x00\x0e\x80\x00\x00\x00\x00\x00\x00\x1c\x00\x7f\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x7f\x00\x19\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x7f\x008\x00\x00\x00\x00\x00\x00\x00\x06\x00\x7f\x002\x00\x00\x00\x00\x00\x00\x00\x06\x00\x7f\x000\x00\x00\x00\x00\x00\x00\x00\x17\x00\x7f\x00t\x00\x00\x00\x00\x00\x00\x00\x03\x00\x7f\x00`\x00\x00\x00\x00\x00\x00\x00\x03\x80\x7f\x00`\x00\x00\x00\x00\x00\x00\x00\x01\x80\x7f\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x01\x80\x7f\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x01\x80\x7f\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x01\xc0\x7f\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x7f\x01\xc0\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x01\x00\x00\x00\x00\xc0\x7f\x01\x80\x00\x00\x00\x1c\x00\x00\x00\x00\xc0\x7f\x01\x90\x00\x00\x007\x00\x00\x00\x02\xc0\x7f\x00\x80\x00\x00\x01o\xff\xf0\x00\x00@\x7f\x07\xe4\x00\x00\x00O\xff\xff\xff\xab\xf8\x7f\x0f\xf0\x00\x00\x00\xcf\xff\xff\xff\x83\xf8\x7f\x00\x00\x00\x00\x00O\xff\xf8\x00\x00\x00\x7f\x00\x00\x00\x00\x00'\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f"
|
||||
Dots_0=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\xa0\x00\n\x00\x00\xa0\x00\x00\x7f\x00\x00\x04\x08\x00@\x80\x04\x08\x00\x00\x7f\x00\x00\x02\x10\x00!\x00\x02\x10\x00\x00\x7f\x00\x00\x04\x08\x00@\x80\x04\x08\x00\x00\x7f\x00\x00 \x01\x02\x00\x10 \x01\x00\x00\x7f\x00\x00\x10\x02\x01\x00 \x10\x02\x00\x00\x7f\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xfc\x00\x0f\xc0\x00\x80\x00\x7f\x00\x00@\x00\xfc\x00\x0f\xc0\x00\x00\x00\x7f\x00\x00@\x00\x84\x00\x08@\x00\x80\x00\x7f\x00\x00\x00\x02\x00\x00 \x00\x02\x00\x00\x7f\x00\x00(\x01\x02\x80\x10(\x01\x00\x00\x7f\x00\x00\x00\x08\x00\x00\x80\x00\x08\x00\x00\x7f\x00\x00\x02\x10\x00!\x00\x02\x10\x00\x00\x7f\x00\x00\x04\x08\x00@\x80\x04\x08\x00\x00\x7f\x00\x00\x01@\x00\x14\x00\x01@\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Dots_1=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\xa0\x00\n\x00\x00\xa0\x00\x00\x7f\x00\x00\x04\x08\x00@\x80\x04\x08\x00\x00\x7f\x00\x00\x03\xf0\x00!\x00\x02\x10\x00\x00\x7f\x00\x00\x07\xf8\x00@\x80\x04\x08\x00\x00\x7f\x00\x00/\xfd\x02\x00\x10 \x01\x00\x00\x7f\x00\x00\x1f\xfe\x01\x00 \x10\x02\x00\x00\x7f\x00\x00\x1f\xfe\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00_\xfe\xfc\x00\x0f\xc0\x00\x80\x00\x7f\x00\x00\x1f\xfe\xfc\x00\x0f\xc0\x00\x00\x00\x7f\x00\x00_\xfe\x84\x00\x08@\x00\x80\x00\x7f\x00\x00\x1f\xfe\x00\x00 \x00\x02\x00\x00\x7f\x00\x00/\xfd\x02\x80\x10(\x01\x00\x00\x7f\x00\x00\x07\xf8\x00\x00\x80\x00\x08\x00\x00\x7f\x00\x00\x03\xf0\x00!\x00\x02\x10\x00\x00\x7f\x00\x00\x04\x08\x00@\x80\x04\x08\x00\x00\x7f\x00\x00\x01@\x00\x14\x00\x01@\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Dots_2=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\xa0\x00\n\x00\x00\xa0\x00\x00\x7f\x00\x00\x04\x08\x00@\x80\x04\x08\x00\x00\x7f\x00\x00\x02\x10\x00?\x00\x02\x10\x00\x00\x7f\x00\x00\x04\x08\x00\x7f\x80\x04\x08\x00\x00\x7f\x00\x00 \x01\x02\xff\xd0 \x01\x00\x00\x7f\x00\x00\x10\x02\x01\xff\xe0\x10\x02\x00\x00\x7f\x00\x00@\x00\x01\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xfd\xff\xef\xc0\x00\x80\x00\x7f\x00\x00@\x00\xfd\xff\xef\xc0\x00\x00\x00\x7f\x00\x00@\x00\x85\xff\xe8@\x00\x80\x00\x7f\x00\x00\x00\x02\x01\xff\xe0\x00\x02\x00\x00\x7f\x00\x00(\x01\x02\xff\xd0(\x01\x00\x00\x7f\x00\x00\x00\x08\x00\x7f\x80\x00\x08\x00\x00\x7f\x00\x00\x02\x10\x00?\x00\x02\x10\x00\x00\x7f\x00\x00\x04\x08\x00@\x80\x04\x08\x00\x00\x7f\x00\x00\x01@\x00\x14\x00\x01@\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Dots_3=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\xa0\x00\n\x00\x00\xa0\x00\x00\x7f\x00\x00\x04\x08\x00@\x80\x04\x08\x00\x00\x7f\x00\x00\x02\x10\x00!\x00\x03\xf0\x00\x00\x7f\x00\x00\x04\x08\x00@\x80\x07\xf8\x00\x00\x7f\x00\x00 \x01\x02\x00\x10/\xfd\x00\x00\x7f\x00\x00\x10\x02\x01\x00 \x1f\xfe\x00\x00\x7f\x00\x00@\x00\x00\x00\x00\x1f\xfe\x00\x00\x7f\x00\x00\x00\x00\xfc\x00\x0f\xdf\xfe\x80\x00\x7f\x00\x00@\x00\xfc\x00\x0f\xdf\xfe\x00\x00\x7f\x00\x00@\x00\x84\x00\x08_\xfe\x80\x00\x7f\x00\x00\x00\x02\x00\x00 \x1f\xfe\x00\x00\x7f\x00\x00(\x01\x02\x80\x10/\xfd\x00\x00\x7f\x00\x00\x00\x08\x00\x00\x80\x07\xf8\x00\x00\x7f\x00\x00\x02\x10\x00!\x00\x03\xf0\x00\x00\x7f\x00\x00\x04\x08\x00@\x80\x04\x08\x00\x00\x7f\x00\x00\x01@\x00\x14\x00\x01@\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Hourglass_0=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xfe\x00\x00\x00\x7f\x00\x00\x00?\xff\xf0\x00\x02\x00\x00\x00\x7f\x00\x00\x00?\xff\xfc\x00\x02\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xfe\x00\x00\x00\x7f\x00\x00\x00\x06\xaa\xaa\xaa\xb0\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\xf0\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06UUUP\x00\x00\x00\x7f\x00\x00\x00\x06\xaa\xaa\xaa\x90\x00\x00\x00\x7f\x00\x00\x00\x06\xaa\xaa\xaa\xb0\x00\x00\x00\x7f\x00\x00\x00\x02UUU0\x00\x00\x00\x7f\x00\x00\x00\x03UUU \x00\x00\x00\x7f\x00\x00\x00\x01\xaa\xaa\xaa`\x00\x00\x00\x7f\x00\x00\x00\x00\xd5UT\xc0\x00\x00\x00\x7f\x00\x00\x00\x00j\xaa\xa9\x80\x00\x00\x00\x7f\x00\x00\x00\x005US\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1a\xaa\xa6\x00\x00\x00\x00\x7f\x00\x00\x00\x00\rUL\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x06\xaa\x98\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03U0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xaa`\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xd4\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00i\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x003\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x006\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc1\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\x88\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\x00`\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x06\x080\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0c\x00\x18\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x18\x08\x0c\x00\x00\x00\x00\x7f\x00\x00\x00\x000\x00\x06\x00\x00\x00\x00\x7f\x00\x00\x00\x00`\x08\x03\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xc0\x00\x01\x80\x00\x00\x00\x7f\x00\x00\x00\x01\x80\x08\x00\xc0\x00\x00\x00\x7f\x00\x00\x00\x03\x00\x00\x00`\x00\x00\x00\x7f\x00\x00\x00\x03\x00\x08\x000\x00\x00\x00\x7f\x00\x00\x00\x02\x00\x00\x000\x00\x00\x00\x7f\x00\x00\x00\x06\x00\n\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00*\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00U@\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x01U@\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x02\xaa\xa8\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x05UT\x10\x00\x00\x00\x7f\x00\x00\x00\x06]\xb6\xdb\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\xf0\x00\x00\x00\x7f\x00\x00\x00\x06\xaa\xaa\xaa\xb0\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xfe\x00\x00\x00\x7f\x00\x00\x00?\xff\xf8\x00\x02\x00\x00\x00\x7f\x00\x00\x00?\xff\xfc\x00\x02\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xfe\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Hourglass_1=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xfe\x00\x00\x00\x7f\x00\x00\x00?\xff\xf0\x00\x02\x00\x00\x00\x7f\x00\x00\x00?\xff\xfc\x00\x02\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xfe\x00\x00\x00\x7f\x00\x00\x00\x06\xaa\xaa\xaa\xb0\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\xf0\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x000\x00\x00\x00\x7f\x00\x00\x00\x02\x00\x00\x000\x00\x00\x00\x7f\x00\x00\x00\x03\x00\x00\x00 \x00\x00\x00\x7f\x00\x00\x00\x01\x80\x00\x00`\x00\x00\x00\x7f\x00\x00\x00\x00\xc0\x00\x00\xc0\x00\x00\x00\x7f\x00\x00\x00\x00`*\x01\x80\x00\x00\x00\x7f\x00\x00\x00\x002\xaa\x83\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x1a\xaa\xa6\x00\x00\x00\x00\x7f\x00\x00\x00\x00\rUL\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x06\xaa\x98\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03U0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\xaa`\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xd4\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00i\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x003\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x006\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00c\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc9\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x01\x80\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\x08`\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x06\x000\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x0c\x08\x18\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x18\x00\x0c\x00\x00\x00\x00\x7f\x00\x00\x00\x000\x08\x06\x00\x00\x00\x00\x7f\x00\x00\x00\x00`\x00\x03\x00\x00\x00\x00\x7f\x00\x00\x00\x00\xc0\x08\x01\x80\x00\x00\x00\x7f\x00\x00\x00\x01\x80\x14\x00\xc0\x00\x00\x00\x7f\x00\x00\x00\x03\x00U\x00`\x00\x00\x00\x7f\x00\x00\x00\x03\x00\xaa\x800\x00\x00\x00\x7f\x00\x00\x00\x02\x05U@0\x00\x00\x00\x7f\x00\x00\x00\x06\x15UT\x10\x00\x00\x00\x7f\x00\x00\x00\x06UUU\x10\x00\x00\x00\x7f\x00\x00\x00\x06\xaa\xaa\xaa\x90\x00\x00\x00\x7f\x00\x00\x00\x06\xaa\xaa\xaa\x90\x00\x00\x00\x7f\x00\x00\x00\x06UUUP\x00\x00\x00\x7f\x00\x00\x00\x06\xaa\xaa\xaa\x90\x00\x00\x00\x7f\x00\x00\x00\x06\xdbm\xb6\xd0\x00\x00\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x7f\x00\x00\x00\x07\xff\xff\xff\xf0\x00\x00\x00\x7f\x00\x00\x00\x06\xaa\xaa\xaa\xb0\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xfe\x00\x00\x00\x7f\x00\x00\x00?\xff\xf8\x00\x02\x00\x00\x00\x7f\x00\x00\x00?\xff\xfc\x00\x02\x00\x00\x00\x7f\x00\x00\x00?\xff\xff\xff\xfe\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Hourglass_2=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00p\x00\x00\x00\x00\x00\x07\x80\x00\x7f\x00\x00\xf0\x00\x00\x00\x00\x00\x07\x80\x00\x7f\x00\x00\x90\x00\x00\x00\x00\x00\x05\x80\x00\x7f\x00\x00\x9f\xfc\x00\x00\x00\x1f\xfc\x80\x00\x7f\x00\x00\x9f\xff\x80\x00\x00\x7f\xfc\x80\x00\x7f\x00\x00\x94\x01\xc0\x00\x00\xc0\x14\x80\x00\x7f\x00\x00\x9c\x00`\x00\x01\x80\x1c\x80\x00\x7f\x00\x00\x94\x000\x00\x03\x00\x14\x80\x00\x7f\x00\x00\x9c\x00\x18\x00\x06\x00\x1c\x80\x00\x7f\x00\x00\x94\x00\x0c\x00\x0c\x00\x14\x80\x00\x7f\x00\x00\x9c\x00\x06\x00\x18\x00\x1c\x80\x00\x7f\x00\x00\x94\x00\x03\x000\x00\x14\x80\x00\x7f\x00\x00\x9c\x00\x01\x80`\x00\x1c\x80\x00\x7f\x00\x00\x94\x00\x00\xc0\xc0\x00\x14\x80\x00\x7f\x00\x00\x9d\x00\x00a\x80\x00\x1c\x80\x00\x7f\x00\x00\x95@\x003\x00\x00\x14\x80\x00\x7f\x00\x00\x9dP\x00\x1e\x00\x00\x1c\x80\x00\x7f\x00\x00\x94\xb4\x00\x0c\x00\x00\x14\x80\x00\x7f\x00\x00\xbdJ@\x00\x00\x00\x1d\x80\x00\x7f\x00\x00\xf4\xb5\xa9\x00\x00\x00\x15\x80\x00\x7f\x00\x00\xfdJU\\\x00\x00\x1f\x80\x00\x7f\x00\x00\xf4\xb5\xaa\xb6\x00\x00\x17\x80\x00\x7f\x00\x00\xfdJUc\x00\x00\x1f\x80\x00\x7f\x00\x00\xf4\xb5\xaa\xc1\x85\x00\x17\x80\x00\x7f\x00\x00\xfdJU\x80\xca\xc0\x1f\x80\x00\x7f\x00\x00\xf4\xb5\xab\x00e*W\x80\x00\x7f\x00\x00\xfdJV\x002\xda\x9f\x80\x00\x7f\x00\x00\xf4\xb5\xac\x00\x19%W\x80\x00\x7f\x00\x00\xfdJX\x00\x0c\xda\x9f\x80\x00\x7f\x00\x00\xf5u\xb0\x00\x06%W\x80\x00\x7f\x00\x00\xfd\n`\x00\x039_\x80\x00\x7f\x00\x00\xf5\xf8\xc0\x00\x01\x87W\x80\x00\x7f\x00\x00\xfc\x03\x80\x00\x00\xf0_\x80\x00\x7f\x00\x00\xff\xff\x00\x00\x00?\xff\x80\x00\x7f\x00\x00\xf8\x00\x00\x00\x00\x00\x0f\x80\x00\x7f\x00\x00\xf0\x00\x00\x00\x00\x00\x07\x80\x00\x7f\x00\x00\xf0\x00\x00\x00\x00\x00\x07\x80\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Timer_0=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x80\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xf3\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x10\x00\x7f\x00\x06\x00\x00\x00\x7f\x00\x00\x008\x07\xff\xf8\x0f\x00\x00\x00\x7f\x00\x00\x00|?\xff\xff\x1f\x80\x00\x00\x7f\x00\x00\x00\xc6\xff\xc1\xff\xb9\xc0\x00\x00\x7f\x00\x00\x01\x87\xf8\x00\x0f\xf0\xe0\x00\x00\x7f\x00\x00\x03\x07\xe0\x00\x01\xf8p\x00\x00\x7f\x00\x00\x03\x1f\x80/\x00|p\x00\x00\x7f\x00\x00\x01\xbe\x00!\x00>\xe0\x00\x00\x7f\x00\x00\x00\xfc\x00!\x00\x0f\xc0\x00\x00\x7f\x00\x00\x00\xf0\x00#\x00\x07\x80\x00\x00\x7f\x00\x00\x01\xe0\x00.\x00\x03\xc0\x00\x00\x7f\x00\x00\x01\xc0\x00(\x00\x01\xe0\x00\x00\x7f\x00\x00\x03\xc0\x00(\x00\x00\xf0\x00\x00\x7f\x00\x00\x07\x80\x00/\x00\x00p\x00\x00\x7f\x00\x00\x07\x00\x00\x00\x00\x00x\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\x00\x008\x00\x00\x7f\x00\x00\x0e\x00\x00\x00\x00\x00<\x00\x00\x7f\x00\x00\x1e\x00\x00\x00\x00\x00\x1c\x00\x00\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x1e\x00\x00\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x0e\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x0e\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x0f\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x07\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x07\x00\x00\x7f\x00\x00y\xe0\x00\x00\x00\x03\xc7\x00\x00\x7f\x00\x00q \x00\x00\x00\x00G\x00\x00\x7f\x00\x00q \x00\x00\x00\x00G\x00\x00\x7f\x00\x00q\xe0\x00\x00\x00\x01\xc7\x00\x00\x7f\x00\x00p \x00\x00\x00\x00\xc7\x00\x00\x7f\x00\x00p \x00\x00\x00\x00G\x00\x00\x7f\x00\x00x \x00\x00\x00\x00\xc7\x00\x00\x7f\x00\x009\xe0\x00\x00\x00\x03\xc7\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x07\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x0f\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x0e\x00\x00\x7f\x00\x00<\x00\x00\x00\x00\x00\x0e\x00\x00\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x0e\x00\x00\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x1c\x00\x00\x7f\x00\x00\x1e\x00\x00\x00\x00\x00\x1c\x00\x00\x7f\x00\x00\x0e\x00\x00\x00\x00\x00<\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\x00\x008\x00\x00\x7f\x00\x00\x07\x80\x00\x1e\x00\x00x\x00\x00\x7f\x00\x00\x03\x80\x00\x10\x00\x00\xf0\x00\x00\x7f\x00\x00\x03\xc0\x00\x10\x00\x01\xe0\x00\x00\x7f\x00\x00\x01\xe0\x00\x10\x00\x01\xe0\x00\x00\x7f\x00\x00\x00\xf0\x00\x1e\x00\x03\xc0\x00\x00\x7f\x00\x00\x00x\x00\x12\x00\x0f\x80\x00\x00\x7f\x00\x00\x00<\x00\x12\x00\x1f\x00\x00\x00\x7f\x00\x00\x00\x1f\x00\x1e\x00>\x00\x00\x00\x7f\x00\x00\x00\x0f\xc0\x00\x00\xfc\x00\x00\x00\x7f\x00\x00\x00\x07\xf0\x00\x03\xf0\x00\x00\x00\x7f\x00\x00\x00\x01\xfe\x00?\xe0\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\xff\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Timer_1=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x80\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xf3\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x10\x00\x7f\x00\x06\x00\x00\x00\x7f\x00\x00\x008\x07\xff\xf8\x0f\x00\x00\x00\x7f\x00\x00\x00|?\xff\xff\x1f\x80\x00\x00\x7f\x00\x00\x00\xc6\xff\xc1\xff\xb9\xc0\x00\x00\x7f\x00\x00\x01\x87\xf8\x00\x0f\xf0\xe0\x00\x00\x7f\x00\x00\x03\x07\xe0\x00\x01\xf8p\x00\x00\x7f\x00\x00\x03\x1f\x80.@|p\x00\x00\x7f\x00\x00\x01\xbe\x00#T>\xe0\x00\x00\x7f\x00\x00\x00\xfc\x00!U\x0f\xc0\x00\x00\x7f\x00\x00\x00\xf0\x00!*\x87\x80\x00\x00\x7f\x00\x00\x01\xe0\x00/U\xa3\xc0\x00\x00\x7f\x00\x00\x01\xc0\x00(*Q\xe0\x00\x00\x7f\x00\x00\x03\xc0\x00(U\xa8\xf0\x00\x00\x7f\x00\x00\x07\x80\x00/*Tp\x00\x00\x7f\x00\x00\x07\x00\x00\x00U\xa8x\x00\x00\x7f\x00\x00\x0f\x00\x00\x00RV8\x00\x00\x7f\x00\x00\x0e\x00\x00\x05m\xa9<\x00\x00\x7f\x00\x00\x1e\x00\x00\n\x92V\x9c\x00\x00\x7f\x00\x00\x1c\x00\x00\x05m\xa9\x1e\x00\x00\x7f\x00\x00\x1c\x00\x00\n\x92V\x8e\x00\x00\x7f\x00\x008\x00\x00\x05m\xa8\x8e\x00\x00\x7f\x00\x008\x00\x00\n\x92W\xcf\x00\x00\x7f\x00\x008\x00\x00\x05m\xa8\x0f\x00\x00\x7f\x00\x008\x00\x00\n\x92P\x07\x00\x00\x7f\x00\x00y\xe0\x00\x05m\xb3\xc7\x00\x00\x7f\x00\x00q \x00\n\x92HG\x00\x00\x7f\x00\x00q \x00\x05m\xb4G\x00\x00\x7f\x00\x00q\xe0\x00\x04\x92I\xc7\x00\x00\x7f\x00\x00p \x00\x00\x00\x00\xc7\x00\x00\x7f\x00\x00p \x00\x00\x00\x00G\x00\x00\x7f\x00\x00x \x00\x00\x00\x00\xc7\x00\x00\x7f\x00\x009\xe0\x00\x00\x00\x03\xc7\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x07\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x0f\x00\x00\x7f\x00\x008\x00\x00\x00\x00\x00\x0e\x00\x00\x7f\x00\x00<\x00\x00\x00\x00\x00\x0e\x00\x00\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x0e\x00\x00\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x1c\x00\x00\x7f\x00\x00\x1e\x00\x00\x00\x00\x00\x1c\x00\x00\x7f\x00\x00\x0e\x00\x00\x00\x00\x00<\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\x00\x008\x00\x00\x7f\x00\x00\x07\x80\x00\x1e\x00\x00x\x00\x00\x7f\x00\x00\x03\x80\x00\x10\x00\x00\xf0\x00\x00\x7f\x00\x00\x03\xc0\x00\x10\x00\x01\xe0\x00\x00\x7f\x00\x00\x01\xe0\x00\x10\x00\x01\xe0\x00\x00\x7f\x00\x00\x00\xf0\x00\x1e\x00\x03\xc0\x00\x00\x7f\x00\x00\x00x\x00\x12\x00\x0f\x80\x00\x00\x7f\x00\x00\x00<\x00\x12\x00\x1f\x00\x00\x00\x7f\x00\x00\x00\x1f\x00\x1e\x00>\x00\x00\x00\x7f\x00\x00\x00\x0f\xc0\x00\x00\xfc\x00\x00\x00\x7f\x00\x00\x00\x07\xf0\x00\x03\xf0\x00\x00\x00\x7f\x00\x00\x00\x01\xfe\x00?\xe0\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\xff\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Timer_2=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x80\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xf3\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x10\x00\x7f\x00\x06\x00\x00\x00\x7f\x00\x00\x008\x07\xff\xf8\x0f\x00\x00\x00\x7f\x00\x00\x00|?\xff\xff\x1f\x80\x00\x00\x7f\x00\x00\x00\xc6\xff\xc1\xff\xb9\xc0\x00\x00\x7f\x00\x00\x01\x87\xf8\x00\x0f\xf0\xe0\x00\x00\x7f\x00\x00\x03\x07\xe0\x00\x01\xf8p\x00\x00\x7f\x00\x00\x03\x1f\x80.@|p\x00\x00\x7f\x00\x00\x01\xbe\x00#T>\xe0\x00\x00\x7f\x00\x00\x00\xfc\x00!*\x0f\xc0\x00\x00\x7f\x00\x00\x00\xf0\x00!UG\x80\x00\x00\x7f\x00\x00\x01\xe0\x00/*\xa3\xc0\x00\x00\x7f\x00\x00\x01\xc0\x00(UQ\xe0\x00\x00\x7f\x00\x00\x03\xc0\x00(*\xa8\xf0\x00\x00\x7f\x00\x00\x07\x80\x00/UTp\x00\x00\x7f\x00\x00\x07\x00\x00\x00UTx\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\xaa\xaa8\x00\x00\x7f\x00\x00\x0e\x00\x00\x05UU<\x00\x00\x7f\x00\x00\x1e\x00\x00\n\xaa\xaa\x9c\x00\x00\x7f\x00\x00\x1c\x00\x00\x05UU\x1e\x00\x00\x7f\x00\x00\x1c\x00\x00\x05UV\x8e\x00\x00\x7f\x00\x008\x00\x00\x05UP\x8e\x00\x00\x7f\x00\x008\x00\x00\n\xaa\xaf\xcf\x00\x00\x7f\x00\x008\x00\x00\x05UP\x0f\x00\x00\x7f\x00\x008\x00\x00\x05UP\x07\x00\x00\x7f\x00\x00y\xe0\x00\x05US\xc7\x00\x00\x7f\x00\x00q \x00\n\xaa\xa8G\x00\x00\x7f\x00\x00q \x00\x05UTG\x00\x00\x7f\x00\x00q\xe0\x00\n\xaa\xa9\xc7\x00\x00\x7f\x00\x00p \x00\x05UT\xc7\x00\x00\x7f\x00\x00p \x00\n\xaa\xa8G\x00\x00\x7f\x00\x00x \x00\x05UP\xc7\x00\x00\x7f\x00\x009\xe0\x00\x05US\xc7\x00\x00\x7f\x00\x008\x00\x00\x05UP\x07\x00\x00\x7f\x00\x008\x00\x00\x05UUO\x00\x00\x7f\x00\x008\x00\x00\x05UUN\x00\x00\x7f\x00\x00<\x00\x00\n\xaa\xaa\x8e\x00\x00\x7f\x00\x00\x1c\x00\x00\x05UUN\x00\x00\x7f\x00\x00\x1c\x00\x00\n\xaa\xaa\x9c\x00\x00\x7f\x00\x00\x1e\x00\x00\x05UU\x1c\x00\x00\x7f\x00\x00\x0e\x00\x00\x05UU<\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\xaa\xaa8\x00\x00\x7f\x00\x00\x07\x80\x00\x1eUTx\x00\x00\x7f\x00\x00\x03\x80\x00\x10\xb5T\xf0\x00\x00\x7f\x00\x00\x03\xc0\x00\x11J\xa9\xe0\x00\x00\x7f\x00\x00\x01\xe0\x00\x10\xb5!\xe0\x00\x00\x7f\x00\x00\x00\xf0\x00\x1eJ\xc3\xc0\x00\x00\x7f\x00\x00\x00x\x00\x12\xb5\x0f\x80\x00\x00\x7f\x00\x00\x00<\x00\x12J\x1f\x00\x00\x00\x7f\x00\x00\x00\x1f\x00\x1e\xb4>\x00\x00\x00\x7f\x00\x00\x00\x0f\xc0\x00@\xfc\x00\x00\x00\x7f\x00\x00\x00\x07\xf0\x00\x03\xf0\x00\x00\x00\x7f\x00\x00\x00\x01\xfe\x00?\xe0\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\xff\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Timer_3=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x80\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xf3\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x10\x00\x7f\x00\x06\x00\x00\x00\x7f\x00\x00\x008\x07\xff\xf8\x0f\x00\x00\x00\x7f\x00\x00\x00|?\xff\xff\x1f\x80\x00\x00\x7f\x00\x00\x00\xc6\xff\xc1\xff\xb9\xc0\x00\x00\x7f\x00\x00\x01\x87\xf8\x00\x0f\xf0\xe0\x00\x00\x7f\x00\x00\x03\x07\xe0\x00\x01\xf8p\x00\x00\x7f\x00\x00\x03\x1f\x80.@|p\x00\x00\x7f\x00\x00\x01\xbe\x00#T>\xe0\x00\x00\x7f\x00\x00\x00\xfc\x00!*\x0f\xc0\x00\x00\x7f\x00\x00\x00\xf0\x00!UG\x80\x00\x00\x7f\x00\x00\x01\xe0\x00/*\xa3\xc0\x00\x00\x7f\x00\x00\x01\xc0\x00(UQ\xe0\x00\x00\x7f\x00\x00\x03\xc0\x00(*\xa8\xf0\x00\x00\x7f\x00\x00\x07\x80\x00/UTp\x00\x00\x7f\x00\x00\x07\x00\x00\x00UTx\x00\x00\x7f\x00\x00\x0f\x00\x00\x00\xaa\xaa8\x00\x00\x7f\x00\x00\x0e\x00\x00\x05UU<\x00\x00\x7f\x00\x00\x1e\x00\x00\n\xaa\xaa\x9c\x00\x00\x7f\x00\x00\x1c\x00\x00\x05UU\x1e\x00\x00\x7f\x00\x00\x1c\x00\x00\x05UV\x8e\x00\x00\x7f\x00\x008\x00\x00\x05UP\x8e\x00\x00\x7f\x00\x008\x00\x00\n\xaa\xaf\xcf\x00\x00\x7f\x00\x008\x00\x00\x05UP\x0f\x00\x00\x7f\x00\x008\x00\x00\x05UP\x07\x00\x00\x7f\x00\x00y\xe0\x00\x05US\xc7\x00\x00\x7f\x00\x00q \x00\n\xaa\xa8G\x00\x00\x7f\x00\x00q \x00\x05UTG\x00\x00\x7f\x00\x00q\xe0\x00\n\xaa\xa9\xc7\x00\x00\x7f\x00\x00p%UUUT\xc7\x00\x00\x7f\x00\x00p"\xaa\xaa\xaa\xa8G\x00\x00\x7f\x00\x00x%UUUP\xc7\x00\x00\x7f\x00\x009\xe5UUUS\xc7\x00\x00\x7f\x00\x008\n\xaa\xaa\xaa\xa8\x07\x00\x00\x7f\x00\x008\xd5UUUUO\x00\x00\x7f\x00\x008UUUUUN\x00\x00\x7f\x00\x00<\xaa\xaa\xaa\xaa\xaa\x8e\x00\x00\x7f\x00\x00\x1cUUUUUN\x00\x00\x7f\x00\x00\x1cUUUUU\x9c\x00\x00\x7f\x00\x00\x1e*\xaa\xaa\xaa\xaa\x1c\x00\x00\x7f\x00\x00\x0e\x15UUUU<\x00\x00\x7f\x00\x00\x0f\x15U@\xaa\xaa8\x00\x00\x7f\x00\x00\x07\x8a\xaa\x9eUTx\x00\x00\x7f\x00\x00\x03\x8a\xaa\x90\xb5T\xf0\x00\x00\x7f\x00\x00\x03\xc2\xaa\x91J\xa9\xe0\x00\x00\x7f\x00\x00\x01\xe2\xaa\x90\xb5!\xe0\x00\x00\x7f\x00\x00\x00\xf0\xaa\x9eJ\xc3\xc0\x00\x00\x7f\x00\x00\x00x*\x92\xb5\x0f\x80\x00\x00\x7f\x00\x00\x00<*\x92J\x1f\x00\x00\x00\x7f\x00\x00\x00\x1f\x05\x1e\xb4>\x00\x00\x00\x7f\x00\x00\x00\x0f\xc0\x80@\xfc\x00\x00\x00\x7f\x00\x00\x00\x07\xf0\x00\x03\xf0\x00\x00\x00\x7f\x00\x00\x00\x01\xfe\x00?\xe0\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\xff\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Timer_4=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xff\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x80\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\xf3\x80\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x10\x00\x7f\x00\x06\x00\x00\x00\x7f\x00\x00\x008\x07\xff\xf8\x0f\x00\x00\x00\x7f\x00\x00\x00|?\xff\xff\x1f\x80\x00\x00\x7f\x00\x00\x00\xc6\xff\xc1\xff\xb9\xc0\x00\x00\x7f\x00\x00\x01\x87\xf8\x00\x0f\xf0\xe0\x00\x00\x7f\x00\x00\x03\x07\xe0\x00\x01\xf8p\x00\x00\x7f\x00\x00\x03\x1f\x81.@|p\x00\x00\x7f\x00\x00\x01\xbe\x15#T>\xe0\x00\x00\x7f\x00\x00\x00\xfc*!*\x0f\xc0\x00\x00\x7f\x00\x00\x00\xf0U!UG\x80\x00\x00\x7f\x00\x00\x01\xe1U/*\xa3\xc0\x00\x00\x7f\x00\x00\x01\xc1U(UQ\xe0\x00\x00\x7f\x00\x00\x03\xc5U(*\xa8\xf0\x00\x00\x7f\x00\x00\x07\x85U/UTp\x00\x00\x7f\x00\x00\x07\x15U\x00UTx\x00\x00\x7f\x00\x00\x0f\n\xaa\x80\xaa\xaa8\x00\x00\x7f\x00\x00\x0e*\xaa\xaa\xaa\xaa<\x00\x00\x7f\x00\x00\x1e*\xaa\xaa\xaa\xaa\x9c\x00\x00\x7f\x00\x00\x1cUUUUU\x1e\x00\x00\x7f\x00\x00\x1cUUUUU\x8e\x00\x00\x7f\x00\x008\x15UUUTN\x00\x00\x7f\x00\x008\xf5UUUW\xcf\x00\x00\x7f\x00\x008\n\xaa\xaa\xaa\xa8\x0f\x00\x00\x7f\x00\x008\x05UUUP\x07\x00\x00\x7f\x00\x00y\xe5UUUS\xc7\x00\x00\x7f\x00\x00q"\xaa\xaa\xaa\xa8G\x00\x00\x7f\x00\x00q%UUUTG\x00\x00\x7f\x00\x00q\xe2\xaa\xaa\xaa\xa9\xc7\x00\x00\x7f\x00\x00p%UUUT\xc7\x00\x00\x7f\x00\x00p"\xaa\xaa\xaa\xa8G\x00\x00\x7f\x00\x00x%UUUP\xc7\x00\x00\x7f\x00\x009\xe5UUUS\xc7\x00\x00\x7f\x00\x008\n\xaa\xaa\xaa\xa8\x07\x00\x00\x7f\x00\x008\xd5UUUUO\x00\x00\x7f\x00\x008UUUUUN\x00\x00\x7f\x00\x00<\xaa\xaa\xaa\xaa\xaa\x8e\x00\x00\x7f\x00\x00\x1cUUUUUN\x00\x00\x7f\x00\x00\x1cUUUUU\x9c\x00\x00\x7f\x00\x00\x1e*\xaa\xaa\xaa\xaa\x1c\x00\x00\x7f\x00\x00\x0e\x15UUUU<\x00\x00\x7f\x00\x00\x0f\x15U@\xaa\xaa8\x00\x00\x7f\x00\x00\x07\x8a\xaa\x9eUTx\x00\x00\x7f\x00\x00\x03\x8a\xaa\x90\xb5T\xf0\x00\x00\x7f\x00\x00\x03\xc2\xaa\x91J\xa9\xe0\x00\x00\x7f\x00\x00\x01\xe2\xaa\x90\xb5!\xe0\x00\x00\x7f\x00\x00\x00\xf0\xaa\x9eJ\xc3\xc0\x00\x00\x7f\x00\x00\x00x*\x92\xb5\x0f\x80\x00\x00\x7f\x00\x00\x00<*\x92J\x1f\x00\x00\x00\x7f\x00\x00\x00\x1f\x05\x1e\xb4>\x00\x00\x00\x7f\x00\x00\x00\x0f\xc0\x80@\xfc\x00\x00\x00\x7f\x00\x00\x00\x07\xf0\x00\x03\xf0\x00\x00\x00\x7f\x00\x00\x00\x01\xfe\x00?\xe0\x00\x00\x00\x7f\x00\x00\x00\x00\x7f\xff\xff\x80\x00\x00\x00\x7f\x00\x00\x00\x00\x1f\xff\xfc\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x03\xff\xe0\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f'
|
||||
Water_level_0=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x01\x00\x00`\x00\x08\x00\x03\x00\x00@\x7f\x03\x80\x00\xf0\x00\x1c\x00\x07\x80\x00\xe0\x7f\x0e\xc0\x01\xd8\x00s\x00\x0e\xc0\x01\xf8\x7f\x1ep\x03\xde\x00\xfb\x80\x1ep\x07\x9c\x7f\xff\x1e?\xe7\xc7\xfc\xf1\xff>?\xcf\xff\xff\xff\xff\xfd\xff\xff\xbf\xff\xef\xff\xf7\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
|
||||
Water_level_1=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x01\x00\x00`\x00\x08\x00\x03\x00\x00@\x7f\x03\x80\x00\xf0\x00\x1c\x00\x07\x80\x00\xe0\x7f\x0e\xc0\x01\xd8\x00s\x00\x0e\xc0\x01\xf8\x7f\x1ep\x03\xde\x00\xfb\x80\x1ep\x07\x9c\x7f\xff\x1e?\xe7\xc7\xfc\xf1\xff>?\xcf\xff\xff\xff\xff\xfd\xff\xff\xbf\xff\xef\xff\xf7\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
|
||||
Water_level_2=b'P4\n89 64\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x01\x00\x00`\x00\x08\x00\x03\x00\x00@\x7f\x03\x80\x00\xf0\x00\x1c\x00\x07\x80\x00\xe0\x7f\x0e\xc0\x01\xd8\x00s\x00\x0e\xc0\x01\xf8\x7f\x1ep\x03\xde\x00\xfb\x80\x1ep\x07\x9c\x7f\xff\x1e?\xe7\xc7\xfc\xf1\xff\x1e?\xcf\xff\xff\xff\xff\xfd\xff\xff?\xff\xef\xff\xf7\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
|
||||
Water_level_3=b'P4\n89 64\n\x01\x00\x00`\x00\x08\x00\x03\x00\x00@\x7f\x03\x80\x00\xf0\x00\x1c\x00\x07\x80\x00\xe0\x7f\x0e\xc0\x01\xd8\x00s\x00\x0e\xc0\x01\xf8\x7f\x1ep\x03\xde\x00\xfb\x80\x1ep\x07\x9c\x7f\xff\x1e?\xe7\xc7\xfc\xf1\xff\x1e?\xcf\xff\xff\xff\xff\xfd\xff\xff?\xff\xef\xff\xf7\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xdc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe1\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xdf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xbf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfc?\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8o\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0O\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x1f\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xe0\x1f\xff\xff\xff\xff\x17\xff\xff\xff\xff\xff\xf0\x0f\xff\xff\xff\xff\x07\xff\xff\xff\xff\xff\xfco\xff\xff\xff\xff\x07\xff\xff\xff\xff\xff\xfe\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
|
||||
115
mixly/boards/default/micropython/build/lib/ps2.py
Normal file
115
mixly/boards/default/micropython/build/lib/ps2.py
Normal file
@@ -0,0 +1,115 @@
|
||||
"""
|
||||
PS2Controller
|
||||
|
||||
MicroPython library for the PS2Controller
|
||||
=======================================================
|
||||
|
||||
#Perform upgrade repair 20220819
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import time
|
||||
from machine import Pin
|
||||
from micropython import const
|
||||
|
||||
PSB_SELECT = const(0x0001)
|
||||
PSB_L3 = const(0x0002)
|
||||
PSB_R3 = const(0x0004)
|
||||
PSB_START = const(0x0008)
|
||||
PSB_PAD_UP = const(0x0010)
|
||||
PSB_PAD_RIGHT = const(0x0020)
|
||||
PSB_PAD_DOWN = const(0x0040)
|
||||
PSB_PAD_LEFT = const(0x0080)
|
||||
PSB_L2 = const(0x0100)
|
||||
PSB_R2 = const(0x0200)
|
||||
PSB_L1 = const(0x0400)
|
||||
PSB_R1 = const(0x0800)
|
||||
PSB_GREEN = const(0x1000)
|
||||
PSB_RED = const(0x2000)
|
||||
PSB_BLUE = const(0x4000)
|
||||
PSB_PINK = const(0x8000)
|
||||
PSB_TRIANGLE = const(0x1000)
|
||||
PSB_CIRCLE = const(0x2000)
|
||||
PSB_CROSS = const(0x4000)
|
||||
PSB_SQUARE = const(0x8000)
|
||||
|
||||
PSS_RX = const(0)
|
||||
PSS_RY = const(1)
|
||||
PSS_LX = const(2)
|
||||
PSS_LY = const(3)
|
||||
|
||||
class PS2Controller:
|
||||
def __init__(self,clk_pin,do_pin,di_pin,cs_pin,mode=1,timeout=1000): #mode: 0 red; 1 green
|
||||
self.di =Pin(di_pin,Pin.IN)
|
||||
self.do =Pin(do_pin,Pin.OUT)
|
||||
self.cs =Pin(cs_pin,Pin.OUT)
|
||||
self.clk=Pin(clk_pin,Pin.OUT)
|
||||
|
||||
self.buttons=0
|
||||
self.last_buttons=0
|
||||
self.rods=(128,128,128,128)
|
||||
self.motor1=0
|
||||
self.motor2=0
|
||||
|
||||
timestamp = time.ticks_ms()
|
||||
while not (self._cmds([0x01,0x42])[1] in [0x41,0x73,0x79,0xF3]):
|
||||
if time.ticks_diff(time.ticks_ms(), timestamp) > timeout:
|
||||
raise AttributeError("Cannot find a PS2Controller",self._cmds([0x01,0x42])[1])
|
||||
|
||||
self._cmds([0x01,0x43,0x00,0x01,0x00]) # 进入配置模式
|
||||
time.sleep_ms(10)
|
||||
self._cmds([0x01,0x44,0x00,mode,0x03,0x00,0x00,0x00,0x00]) # “红绿灯”配置模式
|
||||
time.sleep_ms(10)
|
||||
self._cmds([0x01,0x4D,0x00,0x00,0x01]) # 开启震动模式
|
||||
time.sleep_ms(10)
|
||||
self._cmds([0x01,0x43,0x00,0x00,0x5A,0x5A,0x5A,0x5A,0x5A]) # 完成并保存配置
|
||||
time.sleep_ms(10)
|
||||
|
||||
def _cmd(self,cmd):
|
||||
'''Single byte command sending and receiving'''
|
||||
ret = 0
|
||||
for i in range(8):
|
||||
if cmd & 1 << i:
|
||||
self.do.value(1)
|
||||
else:
|
||||
self.do.value(0)
|
||||
self.clk.value(0)
|
||||
time.sleep_us(10)
|
||||
if self.di.value():
|
||||
ret |= 1 << i
|
||||
self.clk.value(1)
|
||||
self.do.value(1)
|
||||
time.sleep_us(10)
|
||||
return ret
|
||||
|
||||
def _cmds(self,cmds):
|
||||
'''Multi byte command sending and receiving'''
|
||||
self.cs.value(0)
|
||||
buffer=bytearray(9)
|
||||
for i, cmd in enumerate(cmds):
|
||||
buffer[i]=self._cmd(cmd)
|
||||
self.cs.value(1)
|
||||
time.sleep_ms(10)
|
||||
return buffer
|
||||
|
||||
def keydata(self):
|
||||
"""Read the value of the key"""
|
||||
_buffer=self._cmds([0X01, 0X42, 0X00, self.motor1, self.motor2, 0X00, 0X00, 0X00, 0X00])
|
||||
if _buffer[2]==0x5A:
|
||||
handkey=(_buffer[4]<<8)| _buffer[3]
|
||||
self.buttons=-handkey-1 & 0xffff
|
||||
self.rods=(_buffer[5],_buffer[6],_buffer[7],_buffer[8])
|
||||
return self.buttons,self.rods
|
||||
|
||||
def vibration(self,motor1=0,motor2=0):
|
||||
"""Vibration settings"""
|
||||
self.motor1=motor1 #motor1:小电机,只有震和不振
|
||||
self.motor2=0 if motor2<1 else motor2*0xBF//100+0X40 #motor2:大电机,范围0x40-0xff,映射0-100
|
||||
self._cmds([0X01, 0X42, 0X00, self.motor1, self.motor2, 0X00, 0X00, 0X00, 0X00])
|
||||
|
||||
def button(self,psb):
|
||||
return (self.keydata()[0] & psb) > 0
|
||||
|
||||
def analog(self,pss):
|
||||
return self.keydata()[1][pss]
|
||||
215
mixly/boards/default/micropython/build/lib/qmc5883l.py
Normal file
215
mixly/boards/default/micropython/build/lib/qmc5883l.py
Normal file
@@ -0,0 +1,215 @@
|
||||
"""
|
||||
QMC5883L
|
||||
|
||||
MicroPython library for the QMC5883L 3-Axis Magnetic Sensor
|
||||
=======================================================
|
||||
#Preliminary composition 20220217
|
||||
|
||||
by https://github.com/RigacciOrg/py-qmc5883l.git
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import math
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
I2CADDR_DEFAULT = const(0x0D) # Default I2C address
|
||||
|
||||
REG_XOUT_LSB = const(0x00) # Output Data Registers for magnetic sensor.
|
||||
REG_YOUT_LSB = const(0x02) # Output Data Registers for magnetic sensor.
|
||||
REG_ZOUT_LSB = const(0x04) # Output Data Registers for magnetic sensor.
|
||||
REG_STATUS_1 = const(0x06) # Status Register.
|
||||
REG_TOUT_LSB = const(0x07) # Output Data Registers for temperature.
|
||||
|
||||
REG_CONTROL_1 = const(0x09) # Reg to control mode of compass.
|
||||
REG_CONTROL_2 = const(0x0A) # Reg to contro2 mode of compass.
|
||||
REG_RST_PERIOD = const(0x0B) # SET/RESET Period Register.
|
||||
REG_CHIP_ID = const(0x0D) # Chip ID register.
|
||||
|
||||
# Flags for Status Register #1.
|
||||
STAT_DRDY = const(0b00000001) # Data Ready.
|
||||
STAT_OVL = const(0b00000010) # Overflow flag.
|
||||
STAT_DOR = const(0b00000100) # Data skipped for reading.
|
||||
# Flags for Status Register #2.
|
||||
INT_ENB = const(0b00000001) # Interrupt Pin Enabling.
|
||||
SOFT_RST = const(0b10000000) # Soft Reset.
|
||||
# Flags for Control Register 1.
|
||||
MODE_STBY = const(0b00000000) # Standby mode.
|
||||
MODE_CONT = const(0b00000001) # Continuous read mode.
|
||||
ODR_10HZ = const(0b00000000) # Output Data Rate Hz.
|
||||
ODR_50HZ = const(0b00000100)
|
||||
ODR_100HZ = const(0b00001000)
|
||||
ODR_200HZ = const(0b00001100)
|
||||
RNG_2G = const(0b00000000) # Range 2 Gauss: for magnetic-clean environments.
|
||||
RNG_8G = const(0b00010000) # Range 8 Gauss: for strong magnetic fields.
|
||||
OSR_512 = const(0b00000000) # Over Sample Rate 512: less noise, more power.
|
||||
OSR_256 = const(0b01000000)
|
||||
OSR_128 = const(0b10000000)
|
||||
OSR_64 = const(0b11000000)
|
||||
|
||||
class Compass:
|
||||
|
||||
def __init__(self,i2c_bus,ODR=ODR_200HZ,RNG=RNG_8G,OSR=OSR_512):
|
||||
self._device = i2c_bus
|
||||
self._address = I2CADDR_DEFAULT
|
||||
self.output_range = RNG
|
||||
self._declination = 0.0
|
||||
self._calibration = [[1.0, 0.0, 0.0],
|
||||
[0.0, 1.0, 0.0],
|
||||
[0.0, 0.0, 1.0]]
|
||||
self._device.scan()
|
||||
time.sleep(0.1)
|
||||
if self._read_byte(REG_CHIP_ID) != 0xFF:
|
||||
raise AttributeError("Cannot find a QMC5883L")
|
||||
|
||||
self.mode_cont = (MODE_CONT | ODR | RNG | OSR)
|
||||
self.mode_stby = (MODE_STBY | ODR_10HZ | RNG_2G | OSR_64)
|
||||
self.mode_continuous()
|
||||
|
||||
def __del__(self):
|
||||
"""Once finished using the sensor, switch to standby mode."""
|
||||
self.mode_standby()
|
||||
|
||||
def _write_byte(self, reg, val):
|
||||
"""Write memory address"""
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _read_byte(self, reg,nbytes=1):
|
||||
"""Read memory address"""
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def mode_continuous(self):
|
||||
"""Set the device in continuous read mode."""
|
||||
self._write_byte(REG_CONTROL_2, SOFT_RST) # Soft reset.
|
||||
self._write_byte(REG_CONTROL_2, INT_ENB) # Disable interrupt.
|
||||
self._write_byte(REG_RST_PERIOD, 0x01) # Define SET/RESET period.
|
||||
self._write_byte(REG_CONTROL_1, self.mode_cont) # Set operation mode.
|
||||
|
||||
def mode_standby(self):
|
||||
"""Set the device in standby mode."""
|
||||
self._write_byte(REG_CONTROL_2, SOFT_RST)
|
||||
self._write_byte(REG_CONTROL_2, INT_ENB)
|
||||
self._write_byte(REG_RST_PERIOD, 0x01)
|
||||
self._write_byte(REG_CONTROL_1, self.mode_stby) # Set operation mode.
|
||||
|
||||
def _read_word_2c(self, registry):
|
||||
"""Calculate the 2's complement of a two bytes value."""
|
||||
data=self._read_byte(registry,2)
|
||||
val = (data[1] << 8) | data[0]
|
||||
if val >= 0x8000: # 32768
|
||||
return val - 0x10000 # 65536
|
||||
else:
|
||||
return val
|
||||
|
||||
def ready(self):
|
||||
return self._read_byte(REG_STATUS_1)
|
||||
|
||||
def get_data(self):
|
||||
"""Read data from magnetic and temperature data registers."""
|
||||
i = 0
|
||||
[x, y, z, t] = [None, None, None, 0]
|
||||
while i < 20: # Timeout after about 0.20 seconds.
|
||||
status = self.ready()
|
||||
if status & STAT_OVL:
|
||||
# Some values have reached an overflow.
|
||||
if self.output_range == RNG_2G:
|
||||
raise AttributeError("Consider switching to RNG_8G output range")
|
||||
else:
|
||||
raise AttributeError("Magnetic sensor overflow")
|
||||
if status & STAT_DOR:
|
||||
# Previous measure was read partially, sensor in Data Lock.
|
||||
x = self._read_word_2c(REG_XOUT_LSB)
|
||||
y = self._read_word_2c(REG_YOUT_LSB)
|
||||
z = self._read_word_2c(REG_ZOUT_LSB)
|
||||
continue
|
||||
if status & STAT_DRDY:
|
||||
# Data is ready to read.
|
||||
x = self._read_word_2c(REG_XOUT_LSB)
|
||||
y = self._read_word_2c(REG_YOUT_LSB)
|
||||
z = self._read_word_2c(REG_ZOUT_LSB)
|
||||
t = self._read_word_2c(REG_TOUT_LSB)
|
||||
break
|
||||
else:
|
||||
# Waiting for DRDY.
|
||||
time.sleep(0.01)
|
||||
i += 1
|
||||
return [x, y, z, t/100+20]
|
||||
|
||||
def get_magnet_raw(self):
|
||||
"""Get the 3 axis values from magnetic sensor."""
|
||||
[x, y, z, t] = self.get_data()
|
||||
return [x, y, z]
|
||||
|
||||
def get_magnet(self):
|
||||
"""Return the horizontal magnetic sensor vector with (x, y) calibration applied."""
|
||||
[x, y, z] = self.get_magnet_raw()
|
||||
if x is None or y is None:
|
||||
[x1, y1] = [x, y]
|
||||
else:
|
||||
c = self._calibration
|
||||
x1 = x * c[0][0] + y * c[0][1] + c[0][2]
|
||||
y1 = x * c[1][0] + y * c[1][1] + c[1][2]
|
||||
return [x1, y1]
|
||||
|
||||
def get_bearing_raw(self):
|
||||
"""Horizontal bearing (in degrees) from magnetic value X and Y."""
|
||||
[x, y, z] = self.get_magnet_raw()
|
||||
if x is None or y is None:
|
||||
return None
|
||||
else:
|
||||
b = math.degrees(math.atan2(y, x))
|
||||
if b < 0:
|
||||
b += 360.0
|
||||
return b
|
||||
|
||||
def get_bearing(self):
|
||||
"""Horizontal bearing, adjusted by calibration and declination."""
|
||||
[x, y] = self.get_magnet()
|
||||
if x is None or y is None:
|
||||
return None
|
||||
else:
|
||||
b = math.degrees(math.atan2(y, x))
|
||||
if b < 0:
|
||||
b += 360.0
|
||||
b += self._declination
|
||||
if b < 0.0:
|
||||
b += 360.0
|
||||
elif b >= 360.0:
|
||||
b -= 360.0
|
||||
return round(b,2)
|
||||
|
||||
def get_temp(self):
|
||||
"""Raw (uncalibrated) data from temperature sensor."""
|
||||
[x, y, z, t] = self.get_data()
|
||||
return t
|
||||
|
||||
def set_declination(self, value):
|
||||
"""Set the magnetic declination, in degrees."""
|
||||
try:
|
||||
d = float(value)
|
||||
if d < -180.0 or d > 180.0:
|
||||
raise AttributeError('Declination must be >= -180 and <= 180')
|
||||
else:
|
||||
self._declination = d
|
||||
except:
|
||||
raise AttributeError('Declination must be a float value')
|
||||
|
||||
def get_declination(self):
|
||||
"""Return the current set value of magnetic declination."""
|
||||
return self._declination
|
||||
|
||||
def set_calibration(self, value):
|
||||
"""Set the 3x3 matrix for horizontal (x, y) magnetic vector calibration."""
|
||||
c = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
|
||||
try:
|
||||
for i in range(0, 3):
|
||||
for j in range(0, 3):
|
||||
c[i][j] = float(value[i][j])
|
||||
self._calibration = c
|
||||
except:
|
||||
logging.error(u'Calibration must be a 3x3 float matrix.')
|
||||
|
||||
def get_calibration(self):
|
||||
"""Return the current set value of the calibration matrix."""
|
||||
return self._calibration
|
||||
111
mixly/boards/default/micropython/build/lib/qmi8658.py
Normal file
111
mixly/boards/default/micropython/build/lib/qmi8658.py
Normal file
@@ -0,0 +1,111 @@
|
||||
"""
|
||||
QMI8658
|
||||
|
||||
Micropython library for the QMI8658(Accelerometer+Gyroscope)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from math import atan, sqrt, degrees
|
||||
from micropython import const
|
||||
|
||||
QMI8658_REG_DEVICE_ID = const(0x00)
|
||||
|
||||
QMI8658_REG_Ctrl1 = const(0x02) #Serial Interface and Sensor Enable
|
||||
QMI8658_REG_Ctrl2 = const(0x03) #Accelerometer Settings
|
||||
QMI8658_REG_Ctrl3 = const(0x04) #Gyroscope Settings
|
||||
QMI8658_REG_Ctrl5 = const(0x06) #Sensor Data Processing Settings
|
||||
QMI8658_REG_Ctrl7 = const(0x08) #Sensor Data Processing Settings
|
||||
QMI8658_REG_Ctrl9 = const(0x0A) #Host Commands
|
||||
QMI8658_REG_StatusInt = const(0x2D) #Sensor Data Available and Lock Register Address
|
||||
QMI8658_REG_DATA = const(0x33)
|
||||
|
||||
Qmi8658AccRange_2g = 0 #/* +/- 2g range */
|
||||
Qmi8658AccRange_4g = 1 #/* +/- 4g range */
|
||||
Qmi8658AccRange_8g = 2 #/* +/- 8g range */
|
||||
Qmi8658AccRange_16g = 3 #/* +/- 16g range */
|
||||
|
||||
Qmi8658GyrRange_16dps = 0 #/* +-16 degrees per second. */
|
||||
Qmi8658GyrRange_32dps = 1 #/* +-32 degrees per second. */
|
||||
Qmi8658GyrRange_64dps = 2 #/* +-64 degrees per second. */
|
||||
Qmi8658GyrRange_128dps = 3 #/* +-128 degrees per second. */
|
||||
Qmi8658GyrRange_256dps = 4 #/* +-256 degrees per second. */
|
||||
Qmi8658GyrRange_512dps = 5 #/* +-512 degrees per second. */
|
||||
Qmi8658GyrRange_1024dps = 6 #/* +-1024 degrees per second. */
|
||||
Qmi8658GyrRange_2048dps = 7 #/* +-2048 degrees per second. */
|
||||
|
||||
Qmi8658Acc_Gyr_Odr_8000Hz = 0x00 #/* High resolution 8000Hz output rate. */
|
||||
Qmi8658Acc_Gyr_Odr_4000Hz = 0x01 #/* High resolution 4000Hz output rate. */
|
||||
Qmi8658Acc_Gyr_Odr_2000Hz = 0x02 #/* High resolution 2000Hz output rate. */
|
||||
Qmi8658Acc_Gyr_Odr_1000Hz = 0x03 #/* High resolution 1000Hz output rate. */
|
||||
Qmi8658Acc_Gyr_Odr_500Hz = 0x04 #/* High resolution 500Hz output rate. */
|
||||
Qmi8658Acc_Gyr_Odr_250Hz = 0x05 #/* High resolution 250Hz output rate. */
|
||||
Qmi8658Acc_Gyr_Odr_125Hz = 0x06 #/* High resolution 125Hz output rate. */
|
||||
Qmi8658Acc_Gyr_Odr_62_5Hz = 0x07 #/* High resolution 62.5Hz output rate. */
|
||||
Qmi8658Acc_Gyr_Odr_31_25Hz= 0x08 #/* High resolution 31.25Hz output rate. */
|
||||
|
||||
class QMI8658:
|
||||
def __init__(self, i2c_bus,addr=0x6B,AccRange=Qmi8658AccRange_8g,GyrRange=Qmi8658GyrRange_2048dps,Acc_Gyr_Odr=Qmi8658Acc_Gyr_Odr_500Hz):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
if self._chip_id() != 0x05:
|
||||
raise AttributeError("Cannot find a QMI8658")
|
||||
|
||||
self._wreg(QMI8658_REG_Ctrl9,0xA2) #做selftest,提高精度
|
||||
time.sleep(0.1)
|
||||
self._wreg(QMI8658_REG_Ctrl1,0x60)
|
||||
self._wreg(QMI8658_REG_Ctrl7,0x03) #启动
|
||||
self._wreg(QMI8658_REG_Ctrl2,(AccRange<< 4)|Acc_Gyr_Odr) #ACC-500HZ/8G
|
||||
self._wreg(QMI8658_REG_Ctrl3,(GyrRange<< 4)|Acc_Gyr_Odr) #Gyr-500HZ/2048dps
|
||||
self._wreg(QMI8658_REG_Ctrl5,0x75) #Gyr-14%,ACC-5.32%
|
||||
self.gyr_lsb_div= 2**(11-GyrRange)
|
||||
self.acc_lsb_div= 1<<(14-AccRange)
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg,nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _chip_id(self):
|
||||
return self._rreg(QMI8658_REG_DEVICE_ID)
|
||||
|
||||
def status(self):
|
||||
return self._rreg(QMI8658_REG_StatusInt)
|
||||
|
||||
def u2s(self,n):
|
||||
return n if n < (1 << 15) else n - (1 << 16)
|
||||
|
||||
@property
|
||||
def getdata(self):
|
||||
while self.status() == 0x81:
|
||||
time.sleep(0.001)
|
||||
_buffer=self._rreg(QMI8658_REG_DATA,14)
|
||||
tmp= float(self.u2s(_buffer[1]<<8|_buffer[0]))/256.0
|
||||
acc_x=float(self.u2s(_buffer[3]<<8|_buffer[2]))/self.acc_lsb_div
|
||||
acc_y=float(self.u2s(_buffer[5]<<8|_buffer[4]))/self.acc_lsb_div
|
||||
acc_z=float(self.u2s(_buffer[7]<<8|_buffer[6]))/self.acc_lsb_div
|
||||
gyr_x=float(self.u2s(_buffer[9]<<8|_buffer[8]))/self.gyr_lsb_div
|
||||
gyr_y=float(self.u2s(_buffer[11]<<8|_buffer[10]))/self.gyr_lsb_div
|
||||
gyr_z=float(self.u2s(_buffer[13]<<8|_buffer[12]))/self.gyr_lsb_div
|
||||
return (acc_x,acc_y,acc_z),(gyr_x,gyr_y,gyr_z),round(tmp,2)
|
||||
|
||||
def acceleration(self):
|
||||
return self.getdata[0]
|
||||
|
||||
def strength(self):
|
||||
return sqrt(self.getdata[0][0]**2+self.getdata[0][1]**2+self.getdata[0][2]**2)
|
||||
|
||||
def gyroscope(self):
|
||||
return self.getdata[1]
|
||||
|
||||
def temperature(self):
|
||||
return self.getdata[2]
|
||||
|
||||
def eulerangles(self,upright=False):
|
||||
x,y,z = self.acceleration()
|
||||
pitch = degrees(atan(z / sqrt(x ** 2 + y ** 2))) if upright else degrees(atan(y / sqrt(x ** 2 + z ** 2)))
|
||||
roll = degrees(atan(x / sqrt(y ** 2 + z ** 2)))
|
||||
return round(pitch,2),round(roll,2)
|
||||
145
mixly/boards/default/micropython/build/lib/radio.py
Normal file
145
mixly/boards/default/micropython/build/lib/radio.py
Normal file
@@ -0,0 +1,145 @@
|
||||
"""
|
||||
Radio-ESP-NOW
|
||||
|
||||
Micropython library for the Radio-ESP-NOW
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
try:
|
||||
from esp import espnow
|
||||
version = 0
|
||||
except:
|
||||
import espnow
|
||||
version = 1
|
||||
from ubinascii import hexlify, unhexlify
|
||||
import network
|
||||
|
||||
class ESPNow(espnow.ESPNow):
|
||||
def __init__(self, channel=None, txpower=20):
|
||||
self._on_handle = {}
|
||||
self._once_irq = True
|
||||
self._nic = network.WLAN(network.STA_IF) #if version else network.WLAN(network.AP_IF)
|
||||
self._nic.active(True)
|
||||
if channel is not None:
|
||||
self.set_channel(channel, txpower)
|
||||
super().__init__()
|
||||
self.active(True)
|
||||
|
||||
def encrypt(self, peer, pmk, add_peer=True):
|
||||
super().set_pmk((pmk + "0" *16)[:16].encode())
|
||||
if add_peer:
|
||||
super().add_peer(unhexlify(peer), encrypt=True)
|
||||
else:
|
||||
super().del_peer(unhexlify(peer))
|
||||
|
||||
def send(self, peer='ffffffffffff', msg=''):
|
||||
'''Send data after error reporting and effective processing'''
|
||||
try:
|
||||
_peer = unhexlify(peer)
|
||||
return super().send(_peer, str(msg))
|
||||
except OSError as err:
|
||||
if len(err.args) < 2:
|
||||
raise err
|
||||
if err.args[1] == 'ESP_ERR_ESPNOW_NOT_INIT':
|
||||
raise OSError("Radio(ESPNOW) is not activated, unable to transmit data")
|
||||
elif err.args[1] == 'ESP_ERR_ESPNOW_IF':
|
||||
self._nic.active(True)
|
||||
elif err.args[1] == 'ESP_ERR_ESPNOW_NOT_FOUND':
|
||||
super().add_peer(_peer, channel=self.channel)
|
||||
return super().send(_peer, str(msg))
|
||||
elif err.args[1] == 'ESP_ERR_ESPNOW_NO_MEM':
|
||||
raise OSError("internal ESP-NOW buffers are full")
|
||||
elif err.args[1] == 'ESP_ERR_ESPNOW_ARG':
|
||||
raise OSError("invalid argument")
|
||||
else:
|
||||
raise err
|
||||
|
||||
def recv(self):
|
||||
'''Receive data'''
|
||||
if self.any():
|
||||
host, msg = super().recv()
|
||||
return hexlify(host).decode(),msg.decode()
|
||||
else :
|
||||
return None,None
|
||||
|
||||
def set_channel(self, channel=1, txpower=20):
|
||||
if not self._nic.isconnected():
|
||||
self._nic.config(channel=channel, txpower=txpower)
|
||||
else:
|
||||
print("Warning: WiFi is connected, the actual espnow channel is {}".format(self.channel))
|
||||
|
||||
def _cb_handle0(self, event_code, data):
|
||||
'''Callback processing conversion'''
|
||||
if self._on_handle:
|
||||
if isinstance(self._on_handle, list):
|
||||
for func in self._on_handle:
|
||||
cmd = func.__name__.rfind('__')
|
||||
if cmd != -1:
|
||||
cmd=func.__name__[cmd+2:]
|
||||
if cmd == str(data[1].decode()):
|
||||
func(hexlify(data[0]).decode(), data[1].decode())
|
||||
else:
|
||||
func(hexlify(data[0]).decode(), data[1].decode())
|
||||
elif isinstance(self._on_handle, dict):
|
||||
mac = hexlify(data[0]).decode()
|
||||
decoded_msg = str(data[1].decode())
|
||||
if '__all__' in self._on_handle:
|
||||
self._on_handle['__all__'](mac, decoded_msg)
|
||||
if decoded_msg in self._on_handle:
|
||||
self._on_handle[decoded_msg](mac, decoded_msg)
|
||||
else:
|
||||
self._on_handle(hexlify(data[0]).decode(), data[1].decode())
|
||||
|
||||
def _cb_handle1(self, ee):
|
||||
'''Callback processing conversion'''
|
||||
host, msg = super().recv()
|
||||
if self._on_handle:
|
||||
if isinstance(self._on_handle, list):
|
||||
for func in self._on_handle:
|
||||
cmd = func.__name__.rfind('__')
|
||||
if cmd != -1:
|
||||
cmd=func.__name__[cmd+2:]
|
||||
if cmd == str(msg.decode()):
|
||||
func(hexlify(host).decode(), msg.decode())
|
||||
else:
|
||||
func(hexlify(host).decode(), msg.decode())
|
||||
elif isinstance(self._on_handle, dict):
|
||||
mac = hexlify(host).decode()
|
||||
decoded_msg = str(msg.decode())
|
||||
if '__all__' in self._on_handle:
|
||||
self._on_handle['__all__'](mac, decoded_msg)
|
||||
if decoded_msg in self._on_handle:
|
||||
self._on_handle[decoded_msg](mac, decoded_msg)
|
||||
else:
|
||||
self._on_handle(hexlify(host).decode(), msg.decode())
|
||||
|
||||
def recv_cb(self, *args):
|
||||
'''Receive callback (single dictionary or lists)'''
|
||||
if len(args) >= 2:
|
||||
self._on_handle.update({args[0]: args[1]})
|
||||
else:
|
||||
self._on_handle = args[0]
|
||||
|
||||
if self._once_irq:
|
||||
self._once_irq = False
|
||||
if version == 0:
|
||||
self.irq(self._cb_handle0)
|
||||
else:
|
||||
self.irq(self._cb_handle1)
|
||||
|
||||
def info(self):
|
||||
'''Get the paired Mac and rssi'''
|
||||
_info=[]
|
||||
for i in self.peers_table:
|
||||
_info.append((hexlify(i).decode(), self.peers_table[i][0]))
|
||||
return _info
|
||||
|
||||
@property
|
||||
def mac(self):
|
||||
'''Get mac address'''
|
||||
return hexlify(self._nic.config('mac')).decode()
|
||||
|
||||
@property
|
||||
def channel(self):
|
||||
'''Get channel address'''
|
||||
return self._nic.config('channel')
|
||||
279
mixly/boards/default/micropython/build/lib/rc522.py
Normal file
279
mixly/boards/default/micropython/build/lib/rc522.py
Normal file
@@ -0,0 +1,279 @@
|
||||
"""
|
||||
RC522
|
||||
|
||||
Micropython library for the RC522 RFID (I2C&SPI)
|
||||
=======================================================
|
||||
#Preliminary composition 20231204
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
import machine
|
||||
from micropython import const
|
||||
|
||||
RC_OK = True
|
||||
RC_NOTAGERR = None
|
||||
RC_ERR = False
|
||||
RC_REQIDL = const(0x26)
|
||||
RC_REQALL = const(0x52)
|
||||
RC_AUTHENT1A = const(0x60)
|
||||
RC_AUTHENT1B = const(0x61)
|
||||
RC_Version = const(0x37)
|
||||
|
||||
class RC522:
|
||||
def __init__(self, drive_bus,cs_pin=None,addr=0x28):
|
||||
self._device= drive_bus
|
||||
if type(drive_bus) in [machine.I2C,machine.SoftI2C]:
|
||||
self._type=True
|
||||
self._address = addr
|
||||
elif type(drive_bus) in [machine.SPI,machine.SoftSPI]:
|
||||
self._type=False
|
||||
self._cs = machine.Pin(cs_pin, machine.Pin.OUT)
|
||||
else:
|
||||
raise ValueError("RC522 only supports I2C and SPI")
|
||||
|
||||
self.init()
|
||||
self.add_list=[1,2,4,5,6,8,9,10,12,13,14,16,17,18,20,21,22,24,25,26,28,29,30,32,33,34,36,37,38,40,41,42,44,45,46,48,49,50,52,53,54,56,57,58,60,61,62]
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
if self._type:
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
else:
|
||||
self._cs.value(0)
|
||||
self._device.write(b'%c' % int(0xff & ((reg << 1) & 0x7e)))
|
||||
self._device.write(b'%c' % int(0xff & val))
|
||||
self._cs.value(1)
|
||||
|
||||
def _rreg(self, reg):
|
||||
'''Read memory address'''
|
||||
if self._type:
|
||||
return self._device.readfrom_mem(self._address, reg, 1)[0]
|
||||
else:
|
||||
self._cs.value(0)
|
||||
self._device.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80)))
|
||||
val = self._device.read(1)
|
||||
self._cs.value(1)
|
||||
return val[0]
|
||||
|
||||
def _sflags(self, reg, mask):
|
||||
self._wreg(reg, self._rreg(reg) | mask)
|
||||
|
||||
def _cflags(self, reg, mask):
|
||||
self._wreg(reg, self._rreg(reg) & (~mask))
|
||||
|
||||
def _tocard(self, cmd, send):
|
||||
recv = []
|
||||
bits = 0
|
||||
irq_en = 0
|
||||
wait_irq =0
|
||||
n = 0
|
||||
stat = RC_ERR
|
||||
if cmd == 0x0E:
|
||||
irq_en = 0x12
|
||||
wait_irq = 0x10
|
||||
elif cmd == 0x0C:
|
||||
irq_en = 0x77
|
||||
wait_irq = 0x30
|
||||
self._wreg(0x02, irq_en)
|
||||
self._cflags(0x04, 0x80)
|
||||
self._sflags(0x0A, 0x80)
|
||||
self._wreg(0x01, 0x00)
|
||||
for c in send:
|
||||
self._wreg(0x09, c)
|
||||
self._wreg(0x01, cmd)
|
||||
|
||||
if cmd == 0x0C:
|
||||
self._sflags(0x0D, 0x80)
|
||||
|
||||
i = 100
|
||||
while True:
|
||||
n = self._rreg(0x04)
|
||||
i -= 1
|
||||
if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)):
|
||||
break
|
||||
|
||||
self._cflags(0x0D, 0x80)
|
||||
if i:
|
||||
if (self._rreg(0x06) & 0x1B) == 0x00:
|
||||
stat = RC_OK
|
||||
|
||||
if n & irq_en & 0x01:
|
||||
stat = RC_NOTAGERR
|
||||
elif cmd == 0x0C:
|
||||
n = self._rreg(0x0A)
|
||||
lbits = self._rreg(0x0C) & 0x07
|
||||
if lbits != 0:
|
||||
bits = (n - 1) * 8 + lbits
|
||||
else:
|
||||
bits = n * 8
|
||||
if n == 0:
|
||||
n = 1
|
||||
elif n > 16:
|
||||
n = 16
|
||||
for _ in range(n):
|
||||
recv.append(self._rreg(0x09))
|
||||
else:
|
||||
stat = RC_ERR
|
||||
return stat, recv, bits
|
||||
|
||||
def _crc(self, data):
|
||||
self._cflags(0x05, 0x04)
|
||||
self._sflags(0x0A, 0x80)
|
||||
for c in data:
|
||||
self._wreg(0x09, c)
|
||||
self._wreg(0x01, 0x03)
|
||||
i = 0xFF
|
||||
while True:
|
||||
n = self._rreg(0x05)
|
||||
i -= 1
|
||||
if not ((i != 0) and not (n & 0x04)):
|
||||
break
|
||||
return [self._rreg(0x22), self._rreg(0x21)]
|
||||
|
||||
def init(self):
|
||||
self.reset()
|
||||
self._wreg(0x2A, 0x8D)
|
||||
self._wreg(0x2B, 0x3E)
|
||||
self._wreg(0x2D, 30)
|
||||
self._wreg(0x2C, 0)
|
||||
self._wreg(0x15, 0x40)
|
||||
self._wreg(0x11, 0x3D)
|
||||
self._wreg(0x26, 0x68)
|
||||
#A32NQ32C3 Additional Register Configuration
|
||||
if self._rreg(RC_Version) == 0x82:
|
||||
self._wreg(0x12, 0x0)
|
||||
self._wreg(0x13, 0x0)
|
||||
self._wreg(0x14, 0x84)
|
||||
self._wreg(0x18, 0x33)
|
||||
self._wreg(0x0c, 0x10)
|
||||
self.antenna_on()
|
||||
|
||||
def reset(self):
|
||||
self._wreg(0x01, 0x0F)
|
||||
|
||||
def antenna_on(self, on=True):
|
||||
if on and ~(self._rreg(0x14) & 0x03):
|
||||
self._sflags(0x14, 0x03)
|
||||
else:
|
||||
self._cflags(0x14, 0x03)
|
||||
|
||||
def request(self, mode):
|
||||
self._wreg(0x0D, 0x07)
|
||||
stat, recv, bits = self._tocard(0x0C, [mode])
|
||||
if (stat != RC_OK) | (bits != 0x10):
|
||||
stat = RC_ERR
|
||||
return stat, bits
|
||||
|
||||
def anticoll(self):
|
||||
ser_chk = 0
|
||||
ser = [0x93, 0x20]
|
||||
self._wreg(0x0D, 0x00)
|
||||
(stat, recv, bits) = self._tocard(0x0C, ser)
|
||||
|
||||
if stat == RC_OK:
|
||||
if len(recv) == 5:
|
||||
for i in range(4):
|
||||
ser_chk = ser_chk ^ recv[i]
|
||||
if ser_chk != recv[4]:
|
||||
stat = RC_ERR
|
||||
else:
|
||||
stat = RC_ERR
|
||||
return stat, recv
|
||||
|
||||
def select_tag(self, ser):
|
||||
buf = [0x93, 0x70] + ser[:5]
|
||||
buf += self._crc(buf)
|
||||
(stat, recv, bits) = self._tocard(0x0C, buf)
|
||||
return RC_OK if (stat == RC_OK) and (bits == 0x18) else RC_ERR
|
||||
|
||||
def auth(self, mode, addr, sect, ser):
|
||||
return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]
|
||||
|
||||
def stop_crypto1(self):
|
||||
self._cflags(0x08, 0x08)
|
||||
|
||||
def read(self, addr):
|
||||
data = [0x30, addr]
|
||||
data += self._crc(data)
|
||||
(stat, recv, _) = self._tocard(0x0C, data)
|
||||
return recv if stat == RC_OK else None
|
||||
|
||||
def write(self, addr, data):
|
||||
buf = [0xA0, addr]
|
||||
buf += self._crc(buf)
|
||||
(stat, recv, bits) = self._tocard(0x0C, buf)
|
||||
|
||||
if not (stat == RC_OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
|
||||
stat = RC_ERR
|
||||
else:
|
||||
buf = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
||||
for i in range(len(data)):
|
||||
buf[i]=data[i]
|
||||
buf += self._crc(buf)
|
||||
(stat, recv, bits) = self._tocard(0x0C, buf)
|
||||
if not (stat == RC_OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
|
||||
stat = RC_ERR
|
||||
return stat
|
||||
|
||||
def read_card(self,add,x='ALL'):#0:all,i:id,2:content
|
||||
if add>=47:
|
||||
raise AttributeError("Out of address range")
|
||||
stat, tag_type = self.request(RC_REQALL)
|
||||
if stat !=RC_OK:
|
||||
stat, tag_type = self.request(RC_REQALL)
|
||||
if stat == RC_OK:
|
||||
(stat, raw_uid) = self.anticoll()
|
||||
if stat == RC_OK:
|
||||
if self.select_tag(raw_uid) == RC_OK:
|
||||
key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
|
||||
if self.auth(RC_AUTHENT1A, self.add_list[add], key, raw_uid) == RC_OK:
|
||||
card = self.read(self.add_list[add])
|
||||
try:
|
||||
card = bytes(card).decode().replace("\x00", '') if card else None
|
||||
except:
|
||||
card = bytes(card) if card else None
|
||||
self.stop_crypto1()
|
||||
if x == "ALL":
|
||||
return int('{}{}{}{}'.format(raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3])), card
|
||||
elif x == "id":
|
||||
return int('{}{}{}{}'.format(raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3]))
|
||||
elif x == "content":
|
||||
return card
|
||||
|
||||
def write_card(self, data,add):
|
||||
if add>=47:
|
||||
raise AttributeError("Out of address range")
|
||||
stat, tag_type = self.request(RC_REQALL)
|
||||
if stat !=RC_OK:
|
||||
stat, tag_type = self.request(RC_REQALL)
|
||||
if stat == RC_OK:
|
||||
(stat, raw_uid) = self.anticoll()
|
||||
if stat == RC_OK:
|
||||
if self.select_tag(raw_uid) == RC_OK:
|
||||
key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
|
||||
if self.auth(RC_AUTHENT1A, self.add_list[add], key, raw_uid) == RC_OK:
|
||||
try:
|
||||
data =list(data.encode())
|
||||
except:
|
||||
data =list(data)
|
||||
if len(data)>16:
|
||||
raise AttributeError("Input must be less than 16 bytes")
|
||||
stat = self.write(self.add_list[add], data)
|
||||
self.stop_crypto1()
|
||||
if stat == RC_OK:
|
||||
print('Data written to card')
|
||||
return RC_OK
|
||||
else:
|
||||
print('Failed to write data to card')
|
||||
return RC_ERR
|
||||
else:
|
||||
print('Authentication error')
|
||||
return RC_ERR
|
||||
else:
|
||||
print('Failed to select tag')
|
||||
return RC_ERR
|
||||
else:
|
||||
return RC_ERR
|
||||
|
||||
def scan_card(self,stat=RC_REQIDL):
|
||||
return self.request(stat)[0]
|
||||
239
mixly/boards/default/micropython/build/lib/rfm98.py
Normal file
239
mixly/boards/default/micropython/build/lib/rfm98.py
Normal file
@@ -0,0 +1,239 @@
|
||||
"""
|
||||
RFM98
|
||||
|
||||
Micropython library for the RFM98 LoRa
|
||||
=======================================================
|
||||
#Preliminary composition 20220406
|
||||
#Rebuild and optimize execution 20220412
|
||||
#Repair receive mode 20220428
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
import gc
|
||||
import time
|
||||
from machine import Pin
|
||||
from micropython import const
|
||||
|
||||
_REG_FIFO = const(0x00)
|
||||
_REG_OP_MODE = const(0x01)
|
||||
_REG_FRF_MSB = const(0x06)
|
||||
_REG_FRF_MID = const(0x07)
|
||||
_REG_FRF_LSB = const(0x08)
|
||||
_REG_PA_CONFIG = const(0x09)
|
||||
_REG_LNA = const(0x0C)
|
||||
_REG_FIFO_ADDR_PTR = const(0x0D)
|
||||
_REG_FIFO_TX_BASE_ADDR = const(0x0E)
|
||||
_REG_FIFO_RX_BASE_ADDR = const(0x0F)
|
||||
_REG_FIFO_RX_CURRENT_ADDR = const(0x10)
|
||||
_REG_IRQ_FLAGS = const(0x12)
|
||||
_REG_RX_NB_BYTES = const(0x13)
|
||||
_REG_PKT_SNR_VALUE = const(0x19)
|
||||
_REG_PKT_RSSI_VALUE = const(0x1A)
|
||||
_REG_MODEM_CONFIG1 = const(0x1D)
|
||||
_REG_MODEM_CONFIG2 = const(0x1E)
|
||||
_REG_PREAMBLE_MSB = const(0x20)
|
||||
_REG_PREAMBLE_LSB = const(0x21)
|
||||
_REG_PAYLOAD_LENGTH = const(0x22)
|
||||
_REG_MODEM_CONFIG3 = const(0x26)
|
||||
_REG_DIO_MAPPING1 = const(0x40)
|
||||
_REG_DIO_MAPPING2 = const(0x41)
|
||||
_REG_VERSION = const(0x42)
|
||||
_REG_PA_DAC = const(0x4D)
|
||||
_DETECTION_OPTIMIZE = const(0x31)
|
||||
_DETECTION_THRESHOLD = const(0x37)
|
||||
|
||||
_MODE_LONG_RANGE_MODE = const(0x88)
|
||||
_MODE_SLEEP = const(0x00)
|
||||
_MODE_STDBY = const(0x01)
|
||||
_MODE_TX = const(0x03)
|
||||
_MODE_RX = const(0x05)
|
||||
|
||||
class RFM98:
|
||||
def __init__(self,spi,cs_pin,frequency_mhz=433.0,signal_bandwidth=125E3,coding_rate=5,spreading_factor=7,**kw):
|
||||
self._spi = spi
|
||||
self._pin_ss = Pin(cs_pin, Pin.OUT)
|
||||
self._frequency_mhz=frequency_mhz
|
||||
self._signal_bandwidth=signal_bandwidth
|
||||
self._coding_rate=coding_rate
|
||||
self._spreading_factor=spreading_factor
|
||||
self._kw=kw
|
||||
self.init()
|
||||
|
||||
def init(self):
|
||||
for i in range(6):
|
||||
if self._read_u8(_REG_VERSION) == 18: # No device type check!
|
||||
break
|
||||
if i >=5:
|
||||
raise AttributeError("Cannot find a RFM9x")
|
||||
time.sleep(1)
|
||||
|
||||
self.sleep()
|
||||
time.sleep(0.01)
|
||||
if self._read_u8(_REG_OP_MODE) != (_MODE_LONG_RANGE_MODE | _MODE_SLEEP):
|
||||
raise RuntimeError("Failed to configure radio for LoRa mode, check wiring!")
|
||||
self._write_u8(_REG_FIFO_TX_BASE_ADDR, 0x00) # Setup entire 256 byte FIFO
|
||||
self._write_u8(_REG_FIFO_RX_BASE_ADDR, 0x00)
|
||||
|
||||
self.idle()
|
||||
self.coding_rate(self._coding_rate) # CR: 5...8
|
||||
self.frequency_mhz(self._frequency_mhz) # Set frequency_mhz 433±10.00
|
||||
self.signal_bandwidth(self._signal_bandwidth) # BW: 7.8...500 kHz
|
||||
self.spreading_factor(self._spreading_factor) # SF: 6..12
|
||||
self.enable_crc(self._kw.get('enable_crc', True)) # Set enable_crc
|
||||
self.preamble_length(self._kw.get('preamble_length', 6))
|
||||
self.tx_power(self._kw.get('tx_power', 16),self._kw.get('high_power', True))
|
||||
|
||||
self._write_u8(_REG_MODEM_CONFIG3, 0x04) #set AGC - True
|
||||
if 1000 /(self._signal_bandwidth / 2**self._spreading_factor) > 16:
|
||||
self._write_u8(_REG_MODEM_CONFIG3, self._read_u8(_REG_MODEM_CONFIG3) | 0x08)
|
||||
|
||||
def transfer(self, address, value = 0x00):
|
||||
response = bytearray(1)
|
||||
self._pin_ss.value(0)
|
||||
self._spi.write(bytes([address]))
|
||||
self._spi.write_readinto(bytes([value]), response)
|
||||
self._pin_ss.value(1)
|
||||
return response
|
||||
|
||||
def _read_u8(self, address):
|
||||
response = self.transfer(address & 0x7f)
|
||||
return int.from_bytes(response, 'big')
|
||||
|
||||
def _write_u8(self, address, value):
|
||||
self.transfer(address | 0x80, value)
|
||||
|
||||
def idle(self):
|
||||
self._write_u8(_REG_OP_MODE, _MODE_LONG_RANGE_MODE | _MODE_STDBY)
|
||||
|
||||
def sleep(self):
|
||||
self._write_u8(_REG_OP_MODE, _MODE_LONG_RANGE_MODE | _MODE_SLEEP)
|
||||
|
||||
def listen(self):
|
||||
self._write_u8(_REG_OP_MODE, _MODE_LONG_RANGE_MODE | _MODE_RX)
|
||||
self._write_u8(_REG_DIO_MAPPING1, 0x00)
|
||||
self._write_u8(_REG_DIO_MAPPING2, 0x40)
|
||||
|
||||
def transmit(self):
|
||||
self._write_u8(_REG_OP_MODE, _MODE_LONG_RANGE_MODE | _MODE_TX)
|
||||
self._write_u8(_REG_DIO_MAPPING1, 0x01)
|
||||
self._write_u8(_REG_DIO_MAPPING2, 0x00)
|
||||
|
||||
def preamble_length(self, val):
|
||||
self._write_u8(_REG_PREAMBLE_MSB, (val >> 8) & 0xFF)
|
||||
self._write_u8(_REG_PREAMBLE_LSB, val & 0xFF)
|
||||
|
||||
def frequency_mhz(self, val):
|
||||
if val < 410 or val > 525:
|
||||
raise RuntimeError("frequency_mhz must be between 410 and 525")
|
||||
frf = int((val * 1000000.0) /(32000000.0 / 524288)) & 0xFFFFFF
|
||||
self._write_u8(_REG_FRF_MSB, frf >> 16)
|
||||
self._write_u8(_REG_FRF_MID, (frf >> 8) & 0xFF)
|
||||
self._write_u8(_REG_FRF_LSB, frf & 0xFF)
|
||||
|
||||
def tx_power(self, val,high_power=True):
|
||||
if high_power:
|
||||
assert 5 <= val <= 23
|
||||
if val > 20:
|
||||
self._write_u8(_REG_PA_DAC, 0x07)
|
||||
val -= 3
|
||||
else:
|
||||
self._write_u8(_REG_PA_DAC, 0x04)
|
||||
self._write_u8(_REG_PA_CONFIG, 0x80 | (val - 5))
|
||||
else:
|
||||
assert -1 <= val <= 14
|
||||
self._write_u8(_REG_PA_CONFIG, 0x70 | (val +1))
|
||||
|
||||
def packet_rssi(self): #last RSSI reading
|
||||
return self._read_u8(_REG_PKT_RSSI_VALUE)-157
|
||||
|
||||
def packet_snr(self): #last SNR reading
|
||||
snr_byte = self._read_u8(_REG_PKT_SNR_VALUE)
|
||||
return snr_byte/4 if snr_byte<=127 else (snr_byte -256 )/4
|
||||
|
||||
def signal_bandwidth(self, val):
|
||||
bw_bins = (7800, 10400, 15600, 20800, 31250, 41700, 62500, 125000, 250000)
|
||||
for bw_id, cutoff in enumerate(bw_bins):
|
||||
if val <= cutoff:
|
||||
break
|
||||
else:
|
||||
bw_id = 9
|
||||
self._write_u8(_REG_MODEM_CONFIG1,(self._read_u8(_REG_MODEM_CONFIG1) & 0x0F) | (bw_id << 4))
|
||||
if val >= 500000:
|
||||
self._write_u8(_DETECTION_OPTIMIZE,(self._read_u8(_DETECTION_OPTIMIZE) | 0x80))
|
||||
self._write_u8(0x36, 0x02)
|
||||
self._write_u8(0x3A, 0x7F)
|
||||
else:
|
||||
self._write_u8(_DETECTION_OPTIMIZE,(self._read_u8(_DETECTION_OPTIMIZE) & 0x7F))
|
||||
self._write_u8(0x36, 0x03)
|
||||
if val == 7800:
|
||||
self._write_u8(0x2F, 0x48)
|
||||
elif val >= 62500:
|
||||
self._write_u8(0x2F, 0x40)
|
||||
else:
|
||||
self._write_u8(0x2F, 0x44)
|
||||
self._write_u8(0x30, 0)
|
||||
|
||||
def coding_rate(self, val):
|
||||
denominator = min(max(val, 5), 8)
|
||||
cr_id = denominator - 4
|
||||
self._write_u8(_REG_MODEM_CONFIG1,(self._read_u8(_REG_MODEM_CONFIG1) & 0xF1) | (cr_id << 1))
|
||||
|
||||
def spreading_factor(self, val):
|
||||
val = min(max(val, 6), 12)
|
||||
self._write_u8(_DETECTION_OPTIMIZE,self._read_u8(_DETECTION_OPTIMIZE)|0x05 if val == 6 else self._read_u8(_DETECTION_OPTIMIZE)|0x03)
|
||||
self._write_u8(_DETECTION_THRESHOLD, 0x0C if val == 6 else 0x0A)
|
||||
self._write_u8(_REG_MODEM_CONFIG2,((self._read_u8(_REG_MODEM_CONFIG2) & 0x0F)| ((val << 4) & 0xF0)))
|
||||
|
||||
def enable_crc(self, val):
|
||||
if val:
|
||||
self._write_u8(_REG_MODEM_CONFIG2,self._read_u8(_REG_MODEM_CONFIG2) | 0x04)
|
||||
else:
|
||||
self._write_u8(_REG_MODEM_CONFIG2,self._read_u8(_REG_MODEM_CONFIG2) & 0xFB)
|
||||
|
||||
def irq_done(self): #irq status
|
||||
return self._read_u8(_REG_IRQ_FLAGS)
|
||||
|
||||
def send(self,msg,timeout=2):
|
||||
self.idle() # Stop receiving to clear FIFO and keep it clear.
|
||||
self._write_u8(_REG_FIFO_ADDR_PTR, 0x00) # FIFO starts at 0.
|
||||
if isinstance(msg, str):
|
||||
msg = msg.encode()
|
||||
size = min(len(msg), 255)
|
||||
for i in range(size): # write data
|
||||
self._write_u8(_REG_FIFO, msg[i]) # Write payload.
|
||||
self._write_u8(_REG_PAYLOAD_LENGTH, size) # Write payload and header length.
|
||||
self.transmit() # Turn on transmit mode to send out the packet.
|
||||
|
||||
timed_out = False
|
||||
start = time.ticks_ms()
|
||||
while not timed_out and not((self._read_u8(_REG_IRQ_FLAGS) & 0x8) >> 3):
|
||||
if time.ticks_diff(time.ticks_ms(), start) >= timeout * 1000:
|
||||
timed_out = True
|
||||
|
||||
self.idle() # Enter idle mode to stop receiving other packets.
|
||||
gc.collect()
|
||||
self._write_u8(_REG_IRQ_FLAGS, 0xFF) # Clear interrupt.
|
||||
return not timed_out
|
||||
|
||||
def recv(self):
|
||||
if self._read_u8(_REG_OP_MODE) != (_MODE_LONG_RANGE_MODE | _MODE_RX):
|
||||
self.listen() # Enter receive mode
|
||||
|
||||
flags=self.irq_done()
|
||||
if flags & 0x40:
|
||||
self.idle() # Enter idle mode to stop receiving other packets.
|
||||
fifo_length = self._read_u8(_REG_RX_NB_BYTES) # Read the length of the FIFO.
|
||||
if fifo_length > 0: # Read the data from the FIFO.
|
||||
self._write_u8(_REG_FIFO_ADDR_PTR, self._read_u8(_REG_FIFO_RX_CURRENT_ADDR))
|
||||
packet = bytearray()
|
||||
for i in range(fifo_length):
|
||||
packet.append(self._read_u8(_REG_FIFO)) # Read the packet.
|
||||
self._write_u8(_REG_IRQ_FLAGS, 0xFF) # Clear interrupt.
|
||||
gc.collect()
|
||||
try :
|
||||
return bytes(packet).decode()
|
||||
except:
|
||||
return bytes(packet)
|
||||
elif flags== 0x15:
|
||||
print("Timeout not handled , overflow error,will restart!")
|
||||
self.init()
|
||||
69
mixly/boards/default/micropython/build/lib/rtctime.py
Normal file
69
mixly/boards/default/micropython/build/lib/rtctime.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""RTC Time"""
|
||||
import gc
|
||||
from time import *
|
||||
from machine import RTC
|
||||
import usocket as socket
|
||||
import ustruct as struct
|
||||
|
||||
# NTP_DELTA (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
|
||||
NTP_DELTA = 3155673600
|
||||
_weekdayname = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
|
||||
_monthname = (None, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",)
|
||||
|
||||
def ntptime(host="pool.ntp.org", utc=28800):
|
||||
NTP_QUERY = bytearray(48)
|
||||
NTP_QUERY[0] = 0x1B
|
||||
addr = socket.getaddrinfo(host, 123)[0][-1]
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
try:
|
||||
s.settimeout(1)
|
||||
res = s.sendto(NTP_QUERY, addr)
|
||||
msg = s.recv(48)
|
||||
finally:
|
||||
del addr
|
||||
s.close()
|
||||
gc.collect()
|
||||
val = struct.unpack("!I", msg[40:44])[0]
|
||||
return gmtime(val - NTP_DELTA + utc)
|
||||
|
||||
# There's currently no timezone support in MicroPython, and the RTC is set in UTC time.
|
||||
def settime(times):
|
||||
if isinstance(times, str):
|
||||
try:
|
||||
times = eval(times)
|
||||
except:
|
||||
raise ValueError("Clock information format error, use ',' to separate at least 6 numerical values")
|
||||
if type(times) in (tuple, list):
|
||||
if 6 <= len(times) <= 8:
|
||||
RTC().datetime((times[0], times[1], times[2], 0, times[3], times[4], times[5], 0))
|
||||
else:
|
||||
raise ValueError("Settime needs a type of length 6~8")
|
||||
|
||||
def strtime(times=None):
|
||||
if times is None:
|
||||
times = localtime()
|
||||
if isinstance(times, str):
|
||||
try:
|
||||
times = eval(times)
|
||||
except:
|
||||
raise ValueError("Clock information format error, use ',' to separate at least 6 numerical values")
|
||||
if type(times) in (tuple, list):
|
||||
if 6 <= len(times) <= 8:
|
||||
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}'.format(*times)
|
||||
else:
|
||||
raise ValueError("Settime needs a type of length 6~8")
|
||||
|
||||
def rfc1123_time(times=None, utc=28800):
|
||||
if times is None:
|
||||
times = localtime()
|
||||
if isinstance(times, str):
|
||||
try:
|
||||
times = eval(times)
|
||||
except:
|
||||
raise ValueError("Clock information format error, use ',' to separate at least 6 numerical values")
|
||||
if type(times) in (tuple, list):
|
||||
if 6 <= len(times) <= 8:
|
||||
times = localtime(mktime(times) - utc)
|
||||
return '{0}, {1:02d} {2} {3:04d} {4:02d}:{5:02d}:{6:02d} GMT'.format(_weekdayname[times[6]], times[2], _monthname[times[1]], times[0], times[3], times[4], times[5])
|
||||
else:
|
||||
raise ValueError("Settime needs a type of length 6~8")
|
||||
72
mixly/boards/default/micropython/build/lib/sc7a20.py
Normal file
72
mixly/boards/default/micropython/build/lib/sc7a20.py
Normal file
@@ -0,0 +1,72 @@
|
||||
"""
|
||||
SC7A20
|
||||
|
||||
Micropython library for the SC7A20 Accelerometer
|
||||
=================================================
|
||||
#Preliminary composition 20240312
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from math import atan,sqrt,degrees
|
||||
from micropython import const
|
||||
|
||||
SC7A20_ADDRESS = const(0x19)
|
||||
SC7A20_REG_ID = const(0x0F)
|
||||
SC7A20_REG_CTRL1 = const(0x20)
|
||||
SC7A20_REG_CTRL2 = const(0x21)
|
||||
SC7A20_REG_CTRL3 = const(0x22)
|
||||
SC7A20_REG_CTRL4 = const(0x23)
|
||||
SC7A20_REG_DATA = const(0x28)
|
||||
|
||||
#2g 4g 8g 16g
|
||||
_Range_X = (1024,512,256,128)
|
||||
|
||||
class SC7A20:
|
||||
|
||||
def __init__(self, i2c_bus, set_range=2, front=False):
|
||||
self._device = i2c_bus
|
||||
self._address = SC7A20_ADDRESS
|
||||
self._range = set_range #default 8g range
|
||||
self._front = front
|
||||
|
||||
if self._rreg(SC7A20_REG_ID) != 0x11:
|
||||
raise AttributeError("Cannot find a SC7A20")
|
||||
self._wreg(SC7A20_REG_CTRL1, 0X77) #400HZ,xyz使能
|
||||
self._wreg(SC7A20_REG_CTRL2, 0X00) #禁止高通滤波模式
|
||||
self._wreg(SC7A20_REG_CTRL3, 0X00) #禁止中断
|
||||
self._wreg(SC7A20_REG_CTRL4, 0X00 | set_range << 4) #连续更新,设置量程
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, 1)[0]
|
||||
|
||||
def u2s(self, n):
|
||||
return n if n < (1 << 7) else n - (1 << 8)
|
||||
|
||||
@property
|
||||
def getdata(self):
|
||||
x_acc = ((self.u2s(self._rreg(SC7A20_REG_DATA + 1)) << 8 | self._rreg(SC7A20_REG_DATA + 0)) >> 4) / _Range_X[self._range]
|
||||
y_acc = ((self.u2s(self._rreg(SC7A20_REG_DATA + 3)) << 8 | self._rreg(SC7A20_REG_DATA + 2)) >> 4) / _Range_X[self._range]
|
||||
z_acc = ((self.u2s(self._rreg(SC7A20_REG_DATA + 5)) << 8 | self._rreg(SC7A20_REG_DATA + 4)) >> 4) / _Range_X[self._range]
|
||||
return (-x_acc, y_acc, z_acc, None) if self._front else (x_acc, y_acc, z_acc, None)
|
||||
|
||||
def acceleration(self):
|
||||
return self.getdata[0:3]
|
||||
|
||||
def strength(self):
|
||||
from math import sqrt
|
||||
return sqrt(self.getdata[0]**2+self.getdata[1]**2+self.getdata[2]**2)
|
||||
|
||||
def temperature(self):
|
||||
return self.getdata[3]
|
||||
|
||||
def eulerangles(self,upright=False):
|
||||
x, y, z = self.acceleration()
|
||||
pitch = degrees(atan(z / sqrt(x ** 2 + y ** 2))) if upright else degrees(atan(y / sqrt(x ** 2 + z ** 2)))
|
||||
roll = degrees(atan(x / sqrt(y ** 2 + z ** 2)))
|
||||
return round(pitch,2),round(roll,2)
|
||||
231
mixly/boards/default/micropython/build/lib/sdcard.py
Normal file
231
mixly/boards/default/micropython/build/lib/sdcard.py
Normal file
@@ -0,0 +1,231 @@
|
||||
"""
|
||||
MicroPython driver for SD cards using SPI bus.
|
||||
"""
|
||||
import time
|
||||
from machine import Pin
|
||||
from micropython import const
|
||||
|
||||
_CMD_TIMEOUT = const(100)
|
||||
_R1_IDLE_STATE = const(1 << 0)
|
||||
_R1_ILLEGAL_COMMAND = const(1 << 2)
|
||||
_TOKEN_CMD25 = const(0xFC)
|
||||
_TOKEN_STOP_TRAN = const(0xFD)
|
||||
_TOKEN_DATA = const(0xFE)
|
||||
|
||||
class SDCard:
|
||||
def __init__(self, spi, cs_pin=None, baudrate=50000000):
|
||||
self.spi = spi
|
||||
self.cs = Pin(cs_pin, Pin.OUT, value=1) if cs_pin else None
|
||||
self.cmdbuf = bytearray(6)
|
||||
self.dummybuf = bytearray(512)
|
||||
self.tokenbuf = bytearray(1)
|
||||
for i in range(512):
|
||||
self.dummybuf[i] = 0xFF
|
||||
self.dummybuf_memoryview = memoryview(self.dummybuf)
|
||||
# initialise the card
|
||||
self.init_card(baudrate)
|
||||
|
||||
def init_spi(self, baudrate):
|
||||
self.spi.init(baudrate=baudrate, phase=0, polarity=0)
|
||||
|
||||
def init_card(self, baudrate):
|
||||
# init SPI bus; use low data rate for initialisation
|
||||
self.init_spi(100000)
|
||||
# clock card at least 100 cycles with cs high
|
||||
for i in range(16):
|
||||
self.spi.write(b"\xff")
|
||||
# CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts)
|
||||
for _ in range(5):
|
||||
if self.cmd(0, 0, 0x95) == _R1_IDLE_STATE:
|
||||
break
|
||||
else:
|
||||
raise OSError("no SD card")
|
||||
# CMD8: determine card version
|
||||
r = self.cmd(8, 0x01AA, 0x87, 4)
|
||||
if r == _R1_IDLE_STATE:
|
||||
self.init_card_v2()
|
||||
elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND):
|
||||
self.init_card_v1()
|
||||
else:
|
||||
raise OSError("couldn't determine SD card version")
|
||||
# CMD9: response R2 (R1 byte + 16-byte block read)
|
||||
if self.cmd(9, 0, 0, 0, False) != 0:
|
||||
raise OSError("no response from SD card")
|
||||
csd = bytearray(16)
|
||||
self.readinto(csd)
|
||||
if csd[0] & 0xC0 == 0x40: # CSD version 2.0
|
||||
self.sectors = ((csd[8] << 8 | csd[9]) + 1) * 1024
|
||||
elif csd[0] & 0xC0 == 0x00: # CSD version 1.0 (old, <=2GB)
|
||||
c_size = (csd[6] & 0b11) << 10 | csd[7] << 2 | csd[8] >> 6
|
||||
c_size_mult = (csd[9] & 0b11) << 1 | csd[10] >> 7
|
||||
read_bl_len = csd[5] & 0b1111
|
||||
capacity = (c_size + 1) * (2 ** (c_size_mult + 2)) * (2**read_bl_len)
|
||||
self.sectors = capacity // 512
|
||||
else:
|
||||
raise OSError("SD card CSD format not supported")
|
||||
# CMD16: set block length to 512 bytes
|
||||
if self.cmd(16, 512, 0) != 0:
|
||||
raise OSError("can't set 512 block size")
|
||||
# set to high data rate now that it's initialised
|
||||
self.init_spi(baudrate)
|
||||
|
||||
def init_card_v1(self):
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
time.sleep_ms(50)
|
||||
self.cmd(55, 0, 0)
|
||||
if self.cmd(41, 0, 0) == 0:
|
||||
# SDSC card, uses byte addressing in read/write/erase commands
|
||||
self.cdv = 512
|
||||
# print("[SDCard] v1 card")
|
||||
return
|
||||
raise OSError("timeout waiting for v1 card")
|
||||
|
||||
def init_card_v2(self):
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
time.sleep_ms(50)
|
||||
self.cmd(58, 0, 0, 4)
|
||||
self.cmd(55, 0, 0)
|
||||
if self.cmd(41, 0x40000000, 0) == 0:
|
||||
self.cmd(58, 0, 0, -4) # 4-byte response, negative means keep the first byte
|
||||
ocr = self.tokenbuf[0] # get first byte of response, which is OCR
|
||||
if not ocr & 0x40:
|
||||
# SDSC card, uses byte addressing in read/write/erase commands
|
||||
self.cdv = 512
|
||||
else:
|
||||
# SDHC/SDXC card, uses block addressing in read/write/erase commands
|
||||
self.cdv = 1
|
||||
# print("[SDCard] v2 card")
|
||||
return
|
||||
raise OSError("timeout waiting for v2 card")
|
||||
|
||||
def cmd(self, cmd, arg, crc, final=0, release=True, skip1=False):
|
||||
if self.cs: self.cs(0)
|
||||
|
||||
# create and send the command
|
||||
buf = self.cmdbuf
|
||||
buf[0] = 0x40 | cmd
|
||||
buf[1] = arg >> 24
|
||||
buf[2] = arg >> 16
|
||||
buf[3] = arg >> 8
|
||||
buf[4] = arg
|
||||
buf[5] = crc
|
||||
self.spi.write(buf)
|
||||
|
||||
if skip1:
|
||||
self.spi.readinto(self.tokenbuf, 0xFF)
|
||||
# wait for the response (response[7] == 0)
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
self.spi.readinto(self.tokenbuf, 0xFF)
|
||||
response = self.tokenbuf[0]
|
||||
if not (response & 0x80):
|
||||
if final < 0:
|
||||
self.spi.readinto(self.tokenbuf, 0xFF)
|
||||
final = -1 - final
|
||||
for j in range(final):
|
||||
self.spi.write(b"\xff")
|
||||
if release:
|
||||
if self.cs: self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
return response
|
||||
if self.cs: self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
return -1
|
||||
|
||||
def readinto(self, buf):
|
||||
if self.cs: self.cs(0)
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
self.spi.readinto(self.tokenbuf, 0xFF)
|
||||
if self.tokenbuf[0] == _TOKEN_DATA:
|
||||
break
|
||||
time.sleep_ms(1)
|
||||
else:
|
||||
if self.cs: self.cs(1)
|
||||
raise OSError("timeout waiting for response")
|
||||
mv = self.dummybuf_memoryview
|
||||
if len(buf) != len(mv):
|
||||
mv = mv[: len(buf)]
|
||||
self.spi.write_readinto(mv, buf)
|
||||
self.spi.write(b"\xff")
|
||||
self.spi.write(b"\xff")
|
||||
if self.cs: self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
|
||||
def write(self, token, buf):
|
||||
if self.cs: self.cs(0)
|
||||
self.spi.read(1, token)
|
||||
self.spi.write(buf)
|
||||
self.spi.write(b"\xff")
|
||||
self.spi.write(b"\xff")
|
||||
if (self.spi.read(1, 0xFF)[0] & 0x1F) != 0x05:
|
||||
if self.cs: self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
return
|
||||
while self.spi.read(1, 0xFF)[0] == 0:
|
||||
pass
|
||||
if self.cs: self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
|
||||
def write_token(self, token):
|
||||
if self.cs: self.cs(0)
|
||||
self.spi.read(1, token)
|
||||
self.spi.write(b"\xff")
|
||||
while self.spi.read(1, 0xFF)[0] == 0x00:
|
||||
pass
|
||||
if self.cs: self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
|
||||
def readblocks(self, block_num, buf):
|
||||
# workaround for shared bus, required for (at least) some Kingston
|
||||
self.spi.write(b"\xff")
|
||||
|
||||
nblocks = len(buf) // 512
|
||||
assert nblocks and not len(buf) % 512, "Buffer length is invalid"
|
||||
if nblocks == 1:
|
||||
# CMD17: set read address for single block
|
||||
if self.cmd(17, block_num * self.cdv, 0, release=False) != 0:
|
||||
# release the card
|
||||
if self.cs: self.cs(1)
|
||||
raise OSError(5) # EIO
|
||||
# receive the data and release card
|
||||
self.readinto(buf)
|
||||
else:
|
||||
# CMD18: set read address for multiple blocks
|
||||
if self.cmd(18, block_num * self.cdv, 0, release=False) != 0:
|
||||
if self.cs: self.cs(1)
|
||||
raise OSError(5) # EIO
|
||||
offset = 0
|
||||
mv = memoryview(buf)
|
||||
while nblocks:
|
||||
self.readinto(mv[offset : offset + 512])
|
||||
offset += 512
|
||||
nblocks -= 1
|
||||
if self.cmd(12, 0, 0xFF, skip1=True):
|
||||
raise OSError(5) # EIO
|
||||
|
||||
def writeblocks(self, block_num, buf):
|
||||
# workaround for shared bus, required for (at least) some Kingston
|
||||
self.spi.write(b"\xff")
|
||||
nblocks, err = divmod(len(buf), 512)
|
||||
assert nblocks and not err, "Buffer length is invalid"
|
||||
if nblocks == 1:
|
||||
# CMD24: set write address for single block
|
||||
if self.cmd(24, block_num * self.cdv, 0) != 0:
|
||||
raise OSError(5) # EIO
|
||||
self.write(_TOKEN_DATA, buf)
|
||||
else:
|
||||
# CMD25: set write address for first block
|
||||
if self.cmd(25, block_num * self.cdv, 0) != 0:
|
||||
raise OSError(5) # EIO
|
||||
offset = 0
|
||||
mv = memoryview(buf)
|
||||
while nblocks:
|
||||
self.write(_TOKEN_CMD25, mv[offset : offset + 512])
|
||||
offset += 512
|
||||
nblocks -= 1
|
||||
self.write_token(_TOKEN_STOP_TRAN)
|
||||
|
||||
def ioctl(self, op, arg):
|
||||
if op == 4: # get number of blocks
|
||||
return self.sectors
|
||||
if op == 5: # get block size in bytes
|
||||
return 512
|
||||
217
mixly/boards/default/micropython/build/lib/seniverse_api.py
Normal file
217
mixly/boards/default/micropython/build/lib/seniverse_api.py
Normal file
@@ -0,0 +1,217 @@
|
||||
"""
|
||||
Seniverse Weather API
|
||||
|
||||
MicroPython library for Seniverse Weather API
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20220420
|
||||
#https://www.seniverse.com/api
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import json
|
||||
import urequests
|
||||
|
||||
_weather_now="http://api.seniverse.com/v3/weather/now.json?" #天气实况
|
||||
_weather_daily="http://api.seniverse.com/v3/weather/daily.json?" #逐日天气预报
|
||||
_weather_hourly="http://api.seniverse.com/v3/weather/hourly.json?" #逐时天气预报
|
||||
_weather_alarm="http://api.seniverse.com/v3/weather/alarm.json?" #气象灾害预警
|
||||
_life_suggestion="http://api.seniverse.com/v3/life/suggestion.json?" #生活指数
|
||||
_air_now="http://api.seniverse.com/v3/air/now.json?" #空气质量实况
|
||||
_air_daily="http://api.seniverse.com/v3/air/daily.json?" #逐日空气质量预报
|
||||
_air_hourly="http://api.seniverse.com/v3/air/hourly.json?" #逐时空气质量预报
|
||||
_tide_daily="http://api.seniverse.com/v3/tide/daily.json?" #逐时潮汐预报
|
||||
_geo_sun="http://api.seniverse.com/v3/geo/sun.json?" #日出日落
|
||||
_geo_moon="http://api.seniverse.com/v3/geo/moon.json?" #月出月落和月相
|
||||
_location_search="http://api.seniverse.com/v3/location/search.json?" #城市搜索
|
||||
|
||||
#数据请求
|
||||
class API_BASE:
|
||||
_results = None
|
||||
def _urequests_api(self, url):
|
||||
try:
|
||||
results=json.loads(urequests.post(url).text)
|
||||
except Exception as e:
|
||||
raise RuntimeError("API request failed or WiFi is not connected",e)
|
||||
|
||||
if "status" in results.keys():
|
||||
raise ValueError(results["status"])
|
||||
if "results" in results.keys():
|
||||
return results["results"]
|
||||
|
||||
#天气实况 https://docs.seniverse.com/api/weather/now.html
|
||||
class Weather_now(API_BASE):
|
||||
def request(self, key, location):
|
||||
url = "{}key={}&location={}".format(_weather_now, key, location)
|
||||
self._results = self._urequests_api(url)[0]['now']
|
||||
|
||||
def analysis(self, key=None):
|
||||
if key is None:
|
||||
return self._results
|
||||
else:
|
||||
return self._results[key]
|
||||
|
||||
Weather_now = Weather_now()
|
||||
|
||||
#逐日天气预报 https://docs.seniverse.com/api/weather/daily.html
|
||||
class Weather_daily(API_BASE):
|
||||
def request(self, key, location, days=1):
|
||||
url = "{}key={}&location={}&days={}".format(_weather_daily, key, location, days)
|
||||
self._results = self._urequests_api(url)[0]['daily']
|
||||
|
||||
def analysis(self, days=1, key=None):
|
||||
if key is None:
|
||||
return self._results[days]
|
||||
else:
|
||||
return self._results[days][key]
|
||||
|
||||
Weather_daily = Weather_daily()
|
||||
|
||||
#逐时天气预报 https://docs.seniverse.com/api/weather/hourly.html
|
||||
class Weather_hourly(API_BASE):
|
||||
def request(self, key, location, hours=1):
|
||||
url = "{}key={}&location={}&hours={}".format(_weather_hourly, key, location, hours)
|
||||
self._results = self._urequests_api(url)[0]['hourly']
|
||||
|
||||
def analysis(self, hours=1, key=None):
|
||||
if key is None:
|
||||
return self._results[hours]
|
||||
else:
|
||||
return self._results[hours][key]
|
||||
|
||||
#Weather_hourly = Weather_hourly() #暂不开启
|
||||
|
||||
#空气质量实况 https://docs.seniverse.com/api/air/now.html
|
||||
class Air_now(API_BASE):
|
||||
def request(self, key, location):
|
||||
url = "{}key={}&location={}&scope=city".format(_air_now, key, location)
|
||||
self._results = self._urequests_api(url)[0]['air']['city']
|
||||
|
||||
def analysis(self, key=None):
|
||||
if key is None:
|
||||
return self._results
|
||||
else:
|
||||
return self._results[key]
|
||||
|
||||
Air_now = Air_now()
|
||||
|
||||
#逐日空气质量预报 https://docs.seniverse.com/api/air/daily5d.html
|
||||
class Air_daily(API_BASE):
|
||||
def request(self, key, location, days=1):
|
||||
url = "{}key={}&location={}&days={}".format(_air_daily, key, location, days)
|
||||
self._results = self._urequests_api(url)[0]['daily']
|
||||
|
||||
def analysis(self, days=1, key=None):
|
||||
if key is None:
|
||||
return self._results[days]
|
||||
else:
|
||||
return self._results[days][key]
|
||||
|
||||
Air_daily= Air_daily()
|
||||
|
||||
#逐时空气质量预报 https://docs.seniverse.com/api/air/hourly5d.html
|
||||
class Air_hourly(API_BASE):
|
||||
def request(self, key, location, hours=1):
|
||||
url = "{}key={}&location={}&hours={}&days=1".format(_air_hourly, key, location, hours)
|
||||
self._results = self._urequests_api(url)[0]['hourly']
|
||||
|
||||
def analysis(self, hours=1, key=None):
|
||||
if key is None:
|
||||
return self._results[hours]
|
||||
else:
|
||||
return self._results[hours][key]
|
||||
|
||||
#Air_hourly = Air_hourly() #暂不开启
|
||||
|
||||
#气象灾害预警 https://docs.seniverse.com/api/weather/alarm.html
|
||||
class Weather_alarm(API_BASE):
|
||||
def request(self, key, location):
|
||||
url = "{}key={}&location={}".format(_weather_alarm, key, location)
|
||||
results = self._urequests_api(url)[0]['alarms']
|
||||
self._results = results[0] if results else {}
|
||||
|
||||
def analysis(self, key=None):
|
||||
if key is None:
|
||||
return self._results
|
||||
if key in self._results.keys():
|
||||
return self._results[key]
|
||||
|
||||
Weather_alarm = Weather_alarm()
|
||||
|
||||
#生活指数 https://docs.seniverse.com/api/life/suggestion.html
|
||||
class Life_suggestion(API_BASE):
|
||||
def request(self, key, location):
|
||||
url = "{}key={}&location={}".format(_life_suggestion, key, location)
|
||||
self._results = self._urequests_api(url)[0]['suggestion']
|
||||
|
||||
def analysis(self, key=None, brief=False):
|
||||
if key is None:
|
||||
return self._results
|
||||
else:
|
||||
return self._results[key]['brief'] if brief else self._results[key]['details']
|
||||
|
||||
Life_suggestion = Life_suggestion()
|
||||
|
||||
#24时潮汐预报 https://docs.seniverse.com/api/ocean/tide.html
|
||||
class Tide_daily(API_BASE):
|
||||
def request(self, key, location):
|
||||
url = "{}key={}&location={}&days=1".format(_tide_daily, key, location)
|
||||
self._results = self._urequests_api(url)[0]['ports'][0]['data'][0]
|
||||
|
||||
def analysis(self, key=None):
|
||||
if key is None:
|
||||
return self._results
|
||||
else:
|
||||
key = key.split(',')
|
||||
if len(key) == 1:
|
||||
return self._results[key[0]]
|
||||
if len(key) == 2:
|
||||
return self._results['range'][int(key[0])][key[1]]
|
||||
|
||||
Tide_daily = Tide_daily()
|
||||
|
||||
#日出日落 https://docs.seniverse.com/api/geo/sun.html
|
||||
class Geo_sun(API_BASE):
|
||||
def request(self, key, location, days=1):
|
||||
url = "{}key={}&location={}&days={}".format(_geo_sun, key, location, days)
|
||||
self._results = self._urequests_api(url)[0]['sun']
|
||||
|
||||
def analysis(self, days=1, key=None):
|
||||
if key is None:
|
||||
return self._results[days]
|
||||
else:
|
||||
return self._results[days][key]
|
||||
|
||||
Geo_sun = Geo_sun()
|
||||
|
||||
#月出月落和月相 https://docs.seniverse.com/api/geo/moon.html
|
||||
class Geo_moon(API_BASE):
|
||||
def request(self, key, location, days=1):
|
||||
url = "{}key={}&location={}&days={}".format(_geo_moon, key, location, days)
|
||||
self._results = self._urequests_api(url)[0]['moon']
|
||||
|
||||
def analysis(self, days=1, key=None):
|
||||
if key is None:
|
||||
return self._results[days]
|
||||
else:
|
||||
return self._results[days][key]
|
||||
|
||||
Geo_moon = Geo_moon()
|
||||
|
||||
#城市搜索 https://docs.seniverse.com/api/fct/search.html
|
||||
class Location_search(API_BASE):
|
||||
def request(self, key, location):
|
||||
url = "{}key={}&q={}&limit=50".format(_location_search, key, location)
|
||||
results = self._urequests_api(url)
|
||||
self._results = results[0] if results else {}
|
||||
|
||||
def analysis(self, key=None):
|
||||
if key is None:
|
||||
return self._results
|
||||
else:
|
||||
if key in self._results.keys():
|
||||
return self._results[key]
|
||||
|
||||
Location_search = Location_search()
|
||||
|
||||
53
mixly/boards/default/micropython/build/lib/servo.py
Normal file
53
mixly/boards/default/micropython/build/lib/servo.py
Normal file
@@ -0,0 +1,53 @@
|
||||
"""
|
||||
Servo
|
||||
|
||||
MicroPython library for the Servo(0~180°)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20220803
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
from machine import Pin,PWM
|
||||
|
||||
class Servo:
|
||||
__species = {}
|
||||
__first_init = True
|
||||
|
||||
def __new__(cls, pin, *args, **kwargs):
|
||||
if pin not in cls.__species.keys():
|
||||
cls.__first_init = True
|
||||
cls.__species[pin]=object.__new__(cls)
|
||||
return cls.__species[pin]
|
||||
|
||||
def __init__(self,pin):
|
||||
if self.__first_init:
|
||||
self.__first_init = False
|
||||
self._pulse=None
|
||||
self.pwm = PWM(Pin(pin), duty=0, freq=50)
|
||||
|
||||
def servo_write(self,pulse):
|
||||
self._pulse=pulse
|
||||
self.pwm.duty_u16(int(1638.375 + 6553.5 * pulse))
|
||||
|
||||
def servo_read(self):
|
||||
return self._pulse
|
||||
|
||||
#-------Method usage of class--------
|
||||
|
||||
def servo180_angle(pin,angle=None):
|
||||
if angle is None:
|
||||
return int(Servo(pin).servo_read()*180)
|
||||
else:
|
||||
if not 0<= angle <= 180:
|
||||
raise ValueError("The effective range of the servo(180) angle is 0~180°")
|
||||
Servo(pin).servo_write(angle/180)
|
||||
|
||||
|
||||
def servo360_speed(pin,speed=None):
|
||||
if speed is None:
|
||||
return int(Servo(pin).servo_read()*200-100)
|
||||
else:
|
||||
if not -100<= speed <= 100:
|
||||
raise ValueError("The effective range of the servo(360) speed is -100~100%")
|
||||
Servo(pin).servo_write((speed+100)/200)
|
||||
37
mixly/boards/default/micropython/build/lib/sht20.py
Normal file
37
mixly/boards/default/micropython/build/lib/sht20.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from struct import unpack as unp
|
||||
from time import sleep_ms
|
||||
|
||||
# SHT20 default address
|
||||
SHT20_I2CADDR = 64
|
||||
TRI_T_MEASURE_NO_HOLD = b'\xf3'
|
||||
TRI_RH_MEASURE_NO_HOLD = b'\xf5'
|
||||
READ_USER_REG = b'\xe7'
|
||||
WRITE_USER_REG = b'\xe6'
|
||||
SOFT_RESET = b'\xfe'
|
||||
|
||||
class SHT20(object):
|
||||
def __init__(self, i2c_bus):
|
||||
self._address = SHT20_I2CADDR
|
||||
self._bus = i2c_bus
|
||||
|
||||
def get_SHT_temperature(self):
|
||||
self._bus.writeto(self._address, TRI_T_MEASURE_NO_HOLD)
|
||||
sleep_ms(150)
|
||||
origin_data = self._bus.readfrom(self._address, 2)
|
||||
origin_value = unp('>h', origin_data)[0]
|
||||
value = -46.85 + 175.72 * (origin_value / 65536)
|
||||
return value
|
||||
|
||||
def get_SHT_relative_humidity(self):
|
||||
self._bus.writeto(self._address, TRI_RH_MEASURE_NO_HOLD)
|
||||
sleep_ms(150)
|
||||
origin_data = self._bus.readfrom(self._address, 2)
|
||||
origin_value = unp('>H', origin_data)[0]
|
||||
value = -6 + 125 * (origin_value / 65536)
|
||||
return value
|
||||
|
||||
def humidity(self):
|
||||
return self.get_SHT_relative_humidity()
|
||||
|
||||
def temperature(self):
|
||||
return self.get_SHT_temperature()
|
||||
134
mixly/boards/default/micropython/build/lib/shtc3.py
Normal file
134
mixly/boards/default/micropython/build/lib/shtc3.py
Normal file
@@ -0,0 +1,134 @@
|
||||
"""
|
||||
SHTC3
|
||||
|
||||
MicroPython library for the SHTC3(Humidity and Temperature)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20220224
|
||||
#https://github.com/adafruit/Adafruit_CircuitPython_SHTC3.git
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
from time import sleep
|
||||
from micropython import const
|
||||
from struct import unpack_from
|
||||
|
||||
_SHTC3_DEFAULT_ADDR = const(0x70) # SHTC3 I2C Address
|
||||
_SHTC3_READID = const(0xEFC8) # Read Out of ID Register
|
||||
_SHTC3_SOFTRESET = const(0x805D) # Soft Reset
|
||||
_SHTC3_SLEEP = const(0xB098) # Enter sleep mode
|
||||
_SHTC3_WAKEUP = const(0x3517) # Wakeup mode
|
||||
_SHTC3_CHIP_ID = const(0x807)
|
||||
_SHTC3_NORMAL_MEAS = const(0x7866)
|
||||
_SHTC3_LOWPOW_MEAS = const(0x609C)
|
||||
|
||||
class SHTC3:
|
||||
def __init__(self, i2c_bus, addr = _SHTC3_DEFAULT_ADDR):
|
||||
self._device= i2c_bus
|
||||
self._address = addr
|
||||
self._buffer = bytearray(6)
|
||||
self.low_power = False
|
||||
self.sleeping = False
|
||||
self.reset()
|
||||
if self._get_chip_id() != _SHTC3_CHIP_ID:
|
||||
raise AttributeError("Cannot find a SHTC3")
|
||||
|
||||
def _write_command(self, command):
|
||||
"""helper function to write a command to the i2c device"""
|
||||
self._buffer[0] = command >> 8
|
||||
self._buffer[1] = command & 0xFF
|
||||
self._device.writeto(self._address,self._buffer[0:2])
|
||||
|
||||
def _get_chip_id(self): # readCommand(SHTC3_READID, data, 3);
|
||||
"""Determines the chip id of the sensor"""
|
||||
self._write_command(_SHTC3_READID)
|
||||
sleep(0.001)
|
||||
self._device.readfrom_into(self._address,self._buffer)
|
||||
return unpack_from(">H", self._buffer)[0] & 0x083F
|
||||
|
||||
def reset(self):
|
||||
"""Perform a soft reset of the sensor, resetting all settings to their power-on defaults"""
|
||||
self.sleeping = False
|
||||
try:
|
||||
self._write_command(_SHTC3_SOFTRESET)
|
||||
|
||||
except RuntimeError as run_err:
|
||||
if run_err.args and run_err.args[0] != "I2C device address was NACK'd":
|
||||
raise run_err
|
||||
sleep(0.001)
|
||||
|
||||
@property
|
||||
def sleeping(self):
|
||||
"""Determines the sleep state of the sensor"""
|
||||
return self._cached_sleep
|
||||
|
||||
@sleeping.setter
|
||||
def sleeping(self, sleep_enabled):
|
||||
if sleep_enabled:
|
||||
self._write_command(_SHTC3_SLEEP)
|
||||
else:
|
||||
self._write_command(_SHTC3_WAKEUP)
|
||||
sleep(0.001)
|
||||
self._cached_sleep = sleep_enabled
|
||||
|
||||
@property
|
||||
def low_power(self):
|
||||
"""Enables the less accurate low power mode, trading accuracy for power consumption"""
|
||||
return self._low_power
|
||||
|
||||
@low_power.setter
|
||||
def low_power(self, low_power_enabled):
|
||||
self._low_power = low_power_enabled
|
||||
|
||||
@property
|
||||
def measurements(self):
|
||||
"""both `temperature` and `relative_humidity`, read simultaneously"""
|
||||
self.sleeping = False
|
||||
temperature = None
|
||||
humidity = None
|
||||
if self.low_power:
|
||||
self._write_command(_SHTC3_LOWPOW_MEAS)
|
||||
sleep(0.001)
|
||||
else:
|
||||
self._write_command(_SHTC3_NORMAL_MEAS)
|
||||
sleep(0.013)
|
||||
|
||||
self._device.readfrom_into(self._address,self._buffer)
|
||||
|
||||
temp_data = self._buffer[0:2]
|
||||
temp_crc = self._buffer[2]
|
||||
humidity_data = self._buffer[3:5]
|
||||
humidity_crc = self._buffer[5]
|
||||
|
||||
if temp_crc != self._crc8(temp_data) or humidity_crc != self._crc8(humidity_data):
|
||||
return
|
||||
|
||||
raw_temp = unpack_from(">H", temp_data)[0]
|
||||
raw_temp = ((4375 * raw_temp) >> 14) - 4500
|
||||
temperature = raw_temp / 100.0
|
||||
raw_humidity = unpack_from(">H", humidity_data)[0]
|
||||
raw_humidity = (625 * raw_humidity) >> 12
|
||||
humidity = raw_humidity / 100.0
|
||||
|
||||
self.sleeping = True
|
||||
return (temperature, humidity)
|
||||
|
||||
@staticmethod
|
||||
def _crc8(buffer):
|
||||
"""verify the crc8 checksum"""
|
||||
crc = 0xFF
|
||||
for byte in buffer:
|
||||
crc ^= byte
|
||||
for _ in range(8):
|
||||
if crc & 0x80:
|
||||
crc = (crc << 1) ^ 0x31
|
||||
else:
|
||||
crc = crc << 1
|
||||
return crc & 0xFF # return the bottom 8 bits
|
||||
|
||||
def humidity(self):
|
||||
return self.measurements[1]
|
||||
|
||||
def temperature(self):
|
||||
return self.measurements[0]
|
||||
39
mixly/boards/default/micropython/build/lib/sonar.py
Normal file
39
mixly/boards/default/micropython/build/lib/sonar.py
Normal file
@@ -0,0 +1,39 @@
|
||||
"""
|
||||
CS100/HC-SR04
|
||||
|
||||
Micropython library for the CS100/HC-SR04(Ultrasonic ranging)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
from time import sleep_us
|
||||
from machine import Pin, time_pulse_us
|
||||
|
||||
class Sonar:
|
||||
__species = {}
|
||||
__first_init = True
|
||||
|
||||
def __new__(cls, trig, echo, *args, **kwargs):
|
||||
if (trig, echo) not in cls.__species.keys():
|
||||
cls.__first_init = True
|
||||
cls.__species[(trig, echo) ] = object.__new__(cls)
|
||||
return cls.__species[(trig, echo)]
|
||||
|
||||
def __init__(self, trig, echo, max_rang=400):
|
||||
if self.__first_init:
|
||||
self.__first_init = False
|
||||
self.trig = Pin(trig, Pin.OUT, value=0)
|
||||
self.echo = Pin(echo, Pin.IN)
|
||||
self.timeout_us = int(max_rang * 2 * 29.1)
|
||||
|
||||
def checkdist(self):
|
||||
self.trig.value(0)
|
||||
sleep_us(5)
|
||||
self.trig.value(1)
|
||||
sleep_us(10)
|
||||
self.trig.value(0)
|
||||
try:
|
||||
pulse_time = time_pulse_us(self.echo, 1, self.timeout_us)
|
||||
pulse_time = pulse_time if pulse_time >= 0 else self.timeout_us
|
||||
return round(pulse_time / 2 / 29.1, 2) # 1cm each 29.1us
|
||||
except:
|
||||
return None
|
||||
115
mixly/boards/default/micropython/build/lib/spl06_001.py
Normal file
115
mixly/boards/default/micropython/build/lib/spl06_001.py
Normal file
@@ -0,0 +1,115 @@
|
||||
"""
|
||||
_SPL06-001
|
||||
|
||||
MicroPython library for the _SPL06-001(Air pressure sensor)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
_SPL06_ADDRESS = const(0x77)
|
||||
_SPL06_REG_PSR = const(0x00)
|
||||
_SPL06_REG_TMP = const(0x03)
|
||||
_SPL06_PSR_CFG = const(0x06)
|
||||
_SPL06_TMP_CFG = const(0x07)
|
||||
_SPL06_MEAS_CFG = const(0x08)
|
||||
_SPL06_CFG_REG = const(0x09)
|
||||
_SPL06_REG_RST = const(0x0C)
|
||||
_SPL06_REG_ID = const(0x0D)
|
||||
_SPL06_REG_COEF = const(0x10)
|
||||
|
||||
#Parameter selection(sample/sec, times, kT/kP)
|
||||
_SPL06_PSR_TMP_1 = (0<<4, 0, 524288)
|
||||
_SPL06_PSR_TMP_2 = (1<<4, 1, 1572864)
|
||||
_SPL06_PSR_TMP_4 = (2<<4, 2, 3670016)
|
||||
_SPL06_PSR_TMP_8 = (3<<4, 3, 7864320)
|
||||
_SPL06_PSR_TMP_16 = (4<<4, 4, 253952)
|
||||
_SPL06_PSR_TMP_32 = (5<<4, 5, 516096)
|
||||
_SPL06_PSR_TMP_64 = (6<<4, 6, 1040384)
|
||||
_SPL06_PSR_TMP_128 = (7<<4, 7, 2088960)
|
||||
|
||||
class SPL06:
|
||||
def __init__(self, i2c_bus, addr=_SPL06_ADDRESS, rate=_SPL06_PSR_TMP_32):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
self._rate = rate
|
||||
self._psr = 0
|
||||
self._tmp = 0
|
||||
self._alt = 0
|
||||
if self._rreg(_SPL06_REG_ID) != 0x10:
|
||||
raise AttributeError("Cannot find a SPL06-001")
|
||||
self._init()
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)[0] if nbytes<=1 else self._device.readfrom_mem(self._address, reg, nbytes)[0:nbytes]
|
||||
|
||||
def _u2s(self, value, n=8):
|
||||
return value if value < (1 << (n-1)) else value - (1 << n)
|
||||
|
||||
def _status(self):
|
||||
'''数据转换状态'''
|
||||
status = self._rreg(_SPL06_MEAS_CFG)
|
||||
return status & 0x80, status & 0x40, (status >> 4 & 0x01) & (status >> 5 & 0x01) #COEF_RDY,SENSOR_RDY,TMP_RDY+PRS_RDY
|
||||
|
||||
def _init(self):
|
||||
'''软复位'''
|
||||
self._wreg(_SPL06_REG_RST, 0x89)
|
||||
time.sleep_ms(50)
|
||||
'''判断校准数据是否就绪,并读取'''
|
||||
while not self._status()[0]:
|
||||
time.sleep_ms(1)
|
||||
buf = self._rreg(_SPL06_REG_COEF, 18)
|
||||
self._c0 = self._u2s(buf[0] << 4 | buf[1] >> 4, 12)
|
||||
self._c1 = self._u2s((buf[1] & 0x0F) << 8 | buf[2], 12)
|
||||
self._c00 = self._u2s(buf[3] << 12 | buf[4] << 4 | buf[5] >> 4, 20)
|
||||
self._c10 = self._u2s((buf[5] & 0x0F) << 16 | buf[6] << 8 | buf[7], 20)
|
||||
self._c01 = self._u2s(buf[8] << 8 | buf[9], 16)
|
||||
self._c11 = self._u2s(buf[10] << 8 | buf[11], 16)
|
||||
self._c20 = self._u2s(buf[12] << 8 | buf[13], 16)
|
||||
self._c21 = self._u2s(buf[14] << 8 | buf[15], 16)
|
||||
self._c30 = self._u2s(buf[16] << 8 | buf[17], 16)
|
||||
|
||||
'''判断传感器是否就绪,并设置'''
|
||||
while not self._status()[1]:
|
||||
time.sleep_ms(1)
|
||||
self._wreg(_SPL06_MEAS_CFG, 0x07) #Continuous pressure and temperature
|
||||
self._wreg(_SPL06_PSR_CFG, self._rate[0] | self._rate[1]) #Configuration of pressure measurement.
|
||||
self._wreg(_SPL06_TMP_CFG, self._rate[0] | self._rate[1] | 0x80) #Configuration of temperature measurement.
|
||||
self._rreg(_SPL06_REG_PSR, 6)
|
||||
|
||||
if self._rate[1] > 3:
|
||||
self._wreg(_SPL06_CFG_REG, self._rreg(_SPL06_CFG_REG) | 0x0C) #when the oversampling rate is >8 times.
|
||||
|
||||
''''判断数据是否就绪,并读取'''
|
||||
#while not self._status()[2]:
|
||||
#time.sleep_ms(1) #数据就绪需要耗时1s左右
|
||||
|
||||
@property
|
||||
def getdata(self):
|
||||
'''处理获取数据'''
|
||||
if self._status()[2]:
|
||||
buf = self._rreg(_SPL06_REG_PSR, 6)
|
||||
praw = self._u2s(buf[0] << 16 | buf[1] << 8 | buf[2], 24) / self._rate[2]
|
||||
traw = self._u2s(buf[3] << 16 | buf[4] << 8 | buf[5], 24) / self._rate[2]
|
||||
try:
|
||||
self._psr = self._c00 + praw * (self._c10 + praw *(self._c20 + praw * self._c30)) + traw * self._c01 + traw * praw * (self._c11 + praw * self._c21)
|
||||
except:
|
||||
self._psr = 0
|
||||
self._tmp = self._c0 * 0.5 + self._c1 * traw
|
||||
self._alt = (1 - (self._psr / 101325) ** (1/5.255)) * 44330
|
||||
return round(self._psr/100, 2), round(self._tmp, 2), round(self._alt,2)
|
||||
|
||||
def pressure(self):
|
||||
return self.getdata[0]
|
||||
|
||||
def temperature(self):
|
||||
return self.getdata[1]
|
||||
|
||||
def altitude(self, reference=1013.25):
|
||||
return round((pow((reference / 33.8639), 0.190255) - pow((self.getdata[0] / 33.8639), 0.190255)) / 0.000013125214, 2)
|
||||
124
mixly/boards/default/micropython/build/lib/ssd1106.py
Normal file
124
mixly/boards/default/micropython/build/lib/ssd1106.py
Normal file
@@ -0,0 +1,124 @@
|
||||
"""
|
||||
SSD1106
|
||||
|
||||
library for the SSD1x06 OLED128x64
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import uframebuf
|
||||
from micropython import const
|
||||
|
||||
SET_CONTRAST = const(0x81)
|
||||
SET_ENTIRE_ON = const(0xa4)
|
||||
SET_NORM_INV = const(0xa6)
|
||||
SET_DISP_OFF = const(0xae)
|
||||
SET_DISP_ON = const(0xaf)
|
||||
SET_MEM_ADDR = const(0x20)
|
||||
SET_PAGE_ADDR = const(0x22)
|
||||
SET_DISP_START_LINE = const(0x40)
|
||||
SET_SEG_REMAP = const(0xa0)
|
||||
SET_MUX_RATIO = const(0xa8)
|
||||
SET_COM_OUT_DIR = const(0xc0)
|
||||
SET_DISP_OFFSET = const(0xd3)
|
||||
SET_COM_PIN_CFG = const(0xda)
|
||||
SET_DISP_CLK_DIV = const(0xd5)
|
||||
SET_PRECHARGE = const(0xd9)
|
||||
SET_VCOM_DESEL = const(0xdb)
|
||||
SET_CHARGE_PUMP = const(0x8d)
|
||||
SET_COL_ADDR_L = const(0x02)
|
||||
SET_COL_ADDR_H = const(0x10)
|
||||
SET_PAGE_ADDR1 = const(0xb0)
|
||||
SET_CONTRACT_CTRL = const(0x81)
|
||||
|
||||
class SSD1106(uframebuf.FrameBuffer_Uincode):
|
||||
def __init__(self, width, height, external_vcc, l_offset=0, h_offset=0):
|
||||
self._external = external_vcc
|
||||
self._l_offset = l_offset
|
||||
self._h_offset = h_offset
|
||||
self._buffer = bytearray((width + 7) // 8 * height)
|
||||
super().__init__(self._buffer, width, height, uframebuf.MONO_VLSB)
|
||||
self.init_display()
|
||||
|
||||
def init_display(self):
|
||||
for cmd in (
|
||||
SET_DISP_OFF, # display off
|
||||
SET_DISP_CLK_DIV, 0x80, # timing and driving scheme
|
||||
SET_MUX_RATIO, 0x3f, #0xa8
|
||||
SET_DISP_OFFSET, 0x00, #0xd3
|
||||
SET_DISP_START_LINE | 0x00, #start line
|
||||
SET_CHARGE_PUMP, 0x10 if self._external else 0x14,
|
||||
SET_MEM_ADDR, 0x00, # address setting
|
||||
SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
|
||||
SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
|
||||
SET_COM_PIN_CFG, 0x12,
|
||||
SET_CONTRACT_CTRL, 0xcf,
|
||||
SET_PRECHARGE, 0x22 if self._external else 0xf1,
|
||||
SET_VCOM_DESEL, 0x40, # 0.83*Vcc
|
||||
SET_ENTIRE_ON, # output follows RAM contents
|
||||
SET_NORM_INV,
|
||||
SET_DISP_ON): # on
|
||||
self.write_cmd(cmd)
|
||||
self.fill(0)
|
||||
self.show()
|
||||
|
||||
def poweroff(self):
|
||||
self.write_cmd(SET_DISP_OFF)
|
||||
|
||||
def poweron(self):
|
||||
self.write_cmd(SET_DISP_ON)
|
||||
|
||||
def contrast(self, contrast):
|
||||
self.write_cmd(SET_CONTRAST)
|
||||
self.write_cmd(contrast)
|
||||
|
||||
def invert(self, invert):
|
||||
self.write_cmd(SET_NORM_INV | (invert & 1))
|
||||
|
||||
def show(self):
|
||||
for i in range(0, 8):
|
||||
self.write_cmd(SET_PAGE_ADDR1 + i)
|
||||
self.write_cmd(SET_COL_ADDR_L + self._l_offset)
|
||||
self.write_cmd(SET_COL_ADDR_H + self._h_offset)
|
||||
self.write_data(self._buffer[i * 128:(i + 1) * 128]) #send one page display data
|
||||
|
||||
class SSD1106_I2C(SSD1106):
|
||||
def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False, l_offset=0, h_offset=0):
|
||||
self.i2c = i2c
|
||||
self.addr = addr
|
||||
self.temp = bytearray(2)
|
||||
super().__init__(width, height, external_vcc, l_offset, h_offset)
|
||||
|
||||
def write_cmd(self, cmd):
|
||||
self.temp[0] = 0x80
|
||||
self.temp[1] = cmd
|
||||
self.i2c.writeto(self.addr, self.temp)
|
||||
|
||||
def write_data(self, buf):
|
||||
tmp = bytearray([0x40])
|
||||
self.i2c.writeto(self.addr, tmp+buf)
|
||||
|
||||
class SSD1106_SPI(SSD1106):
|
||||
def __init__(self, width, height, spi, dc, cs, external_vcc=False, l_offset=0, h_offset=0):
|
||||
self.rate = 10 * 1024 * 1024
|
||||
dc.init(dc.OUT, value=0)
|
||||
cs.init(cs.OUT, value=1)
|
||||
self.spi = spi
|
||||
self.dc = dc
|
||||
self.cs = cs
|
||||
super().__init__(width, height, external_vcc, l_offset, h_offset)
|
||||
|
||||
def write_cmd(self, cmd):
|
||||
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
|
||||
self.cs(1)
|
||||
self.dc(0)
|
||||
self.cs(0)
|
||||
self.spi.write(bytearray([cmd]))
|
||||
self.cs(1)
|
||||
|
||||
def write_data(self, buf):
|
||||
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
|
||||
self.cs(1)
|
||||
self.dc(1)
|
||||
self.cs(0)
|
||||
self.spi.write(buf)
|
||||
self.cs(1)
|
||||
117
mixly/boards/default/micropython/build/lib/st7735.py
Normal file
117
mixly/boards/default/micropython/build/lib/st7735.py
Normal file
@@ -0,0 +1,117 @@
|
||||
"""
|
||||
ST7735
|
||||
|
||||
MicroPython library for the ST7735(TFT-SPI)
|
||||
=======================================================
|
||||
#Preliminary composition 20230822
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time, uframebuf
|
||||
from machine import Pin, PWM
|
||||
from micropython import const
|
||||
|
||||
_CMD_SWRESET = const(0x01)
|
||||
_CMD_SLPOUT = const(0x11)
|
||||
_CMD_PTLON = const(0x12)
|
||||
_CMD_NORON = const(0x13)
|
||||
_CMD_INVOFF = const(0x20)
|
||||
_CMD_INVON = const(0x21)
|
||||
_CMD_DISPOFF = const(0x28)
|
||||
_CMD_DISPON = const(0x29)
|
||||
_CMD_CASET = const(0x2A)
|
||||
_CMD_RASET = const(0x2B)
|
||||
_CMD_RAMWR = const(0x2C)
|
||||
_CMD_RAMRD = const(0x2E)
|
||||
_CMD_PTLAR = const(0x30)
|
||||
_CMD_COLMOD = const(0x3A)
|
||||
_CMD_MADCTL = const(0x36)
|
||||
_CMD_FRMCTR1 = const(0xB1)
|
||||
_CMD_FRMCTR2 = const(0xB2)
|
||||
_CMD_FRMCTR3 = const(0xB3)
|
||||
_CMD_INVCTR = const(0xB4)
|
||||
_CMD_PWCTR1 = const(0xC0)
|
||||
_CMD_PWCTR2 = const(0xC1)
|
||||
_CMD_PWCTR3 = const(0xC2)
|
||||
_CMD_PWCTR4 = const(0xC3)
|
||||
_CMD_PWCTR5 = const(0xC4)
|
||||
_CMD_VMCTR1 = const(0xC5)
|
||||
_CMD_GMCTRP1 = const(0xE0)
|
||||
_CMD_GMCTRN1 = const(0xE1)
|
||||
|
||||
class ST7735(uframebuf.FrameBuffer_Uincode):
|
||||
def __init__(self, spi, width, height, dc_pin=None, cs_pin=None, bl_pin=None, font_address=0x700000, rotation=0):
|
||||
self.spi = spi
|
||||
self.dc = Pin(dc_pin, Pin.OUT, value=1)
|
||||
self.cs = Pin(cs_pin, Pin.OUT, value=1)
|
||||
self._buffer = bytearray(width * height * 2)
|
||||
super().__init__(self._buffer, width, height, uframebuf.RGB565)
|
||||
self.font(font_address)
|
||||
self._init()
|
||||
self.rotation(rotation)
|
||||
self.fill(0)
|
||||
self.show()
|
||||
time.sleep_ms(100)
|
||||
self._brightness = 0.6
|
||||
self.bl_led = PWM(Pin(bl_pin), duty_u16=int(self._brightness * 60000)) if bl_pin else None
|
||||
|
||||
def _write(self, cmd, dat = None):
|
||||
self.cs.off()
|
||||
self.dc.off()
|
||||
self.spi.write(bytearray([cmd]))
|
||||
self.cs.on()
|
||||
if dat is not None:
|
||||
self.cs.off()
|
||||
self.dc.on()
|
||||
self.spi.write(dat)
|
||||
self.cs.on()
|
||||
|
||||
def _init(self):
|
||||
"""Display initialization configuration"""
|
||||
for cmd, data, delay in [
|
||||
(_CMD_SWRESET, None, 100),
|
||||
(_CMD_SLPOUT, None, 200),
|
||||
(_CMD_FRMCTR1, b'\x01\x2c\x2d', 10),
|
||||
(_CMD_FRMCTR2, b'\x01\x2c\x2d', 10),
|
||||
(_CMD_FRMCTR3, b'\x01\x2c\x2d', 10),
|
||||
(_CMD_INVCTR, b'\x07', None),
|
||||
(_CMD_PWCTR1, b'\xa2\x02\x84', 10),
|
||||
(_CMD_PWCTR2, b'\xc5', None),
|
||||
(_CMD_PWCTR3, b'\x0a\x00', None),
|
||||
(_CMD_PWCTR4, b'\x8a\x2a', None),
|
||||
(_CMD_PWCTR5, b'\x8a\xee', None),
|
||||
(_CMD_VMCTR1, b'\x0e', None),
|
||||
(_CMD_GMCTRP1, b'\x02\x1c\x07\x12\x37\x32\x29\x2d\x29\x25\x2b\x39\x00\x01\x03\x10', None),
|
||||
(_CMD_GMCTRN1, b'\x03\x1d\x07\x06\x2e\x2c\x29\x2d\x2e\x2e\x37\x3f\x00\x00\x02\x10', None),
|
||||
(_CMD_COLMOD, b'\x05', 10),
|
||||
(_CMD_NORON, None, 10),
|
||||
(_CMD_DISPON, None, 200),
|
||||
]:
|
||||
self._write(cmd, data)
|
||||
if delay:
|
||||
time.sleep_us(delay)
|
||||
|
||||
def rotation(self, rotation):
|
||||
self._write(_CMD_MADCTL, b'\x60') if rotation else self._write(_CMD_MADCTL, b'\xa0')
|
||||
self._write(_CMD_CASET, b'\x01\x01\x01\xa0')
|
||||
self._write(_CMD_RASET, b'\x02\x02\x02\x81')
|
||||
|
||||
def get_brightness(self):
|
||||
return self._brightness
|
||||
|
||||
def set_brightness(self, brightness):
|
||||
if not 0.0 <= brightness <= 1.0:
|
||||
raise ValueError("Brightness must be a decimal number in the range: 0.0~1.0")
|
||||
self._brightness = brightness
|
||||
self.bl_led.duty_u16(int(brightness*60000))
|
||||
|
||||
def color(self, red, green=None, blue=None):
|
||||
""" Convert red, green and blue values (0-255) into a 16-bit 565 encoding."""
|
||||
if green is None or blue is None:
|
||||
return red
|
||||
else:
|
||||
return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3
|
||||
|
||||
def show(self):
|
||||
"""Refresh the display and show the changes."""
|
||||
self._write(_CMD_RAMWR, self._buffer)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user