Skip to content

Commit 8ec31a6

Browse files
committed
features/unit/scales: high precision I2C port weighing sensor
1 parent 666d836 commit 8ec31a6

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

m5stack/libs/unit/scales.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
from machine import I2C
2+
from .pahub import PAHUBUnit
3+
from .unit_helper import UnitError
4+
import time
5+
import struct
6+
7+
try:
8+
from typing import Union
9+
except ImportError:
10+
pass
11+
12+
13+
SCALES_ADDR = 0x26
14+
15+
############# BUTTON STATUS ##############
16+
BUTTON_SHORT = 0x20
17+
BUTTON_LONG = 0x21
18+
BUTTON_STATUS = 0x22
19+
BUTTON_OFFSET = 0x23
20+
21+
############## LED CONTROL ###############
22+
LED_SYNC = 0x25
23+
LED_RED = 0x50
24+
LED_GREEN = 0x51
25+
LED_BLUE = 0x52
26+
27+
######## SCALES STATUS & CONTROL #########
28+
RAW_ADC = 0x10
29+
GET_WEIGHT = 0x14
30+
OFFSET_ADC = 0x18
31+
SOFT_OFFSET = 0x24
32+
33+
############## CALIBRATION ###############
34+
CALI_ZERO = 0x30
35+
CALI_LOAD = 0x32
36+
37+
############# DEVICE STATUS ##############
38+
FW_VER_REG = 0xFE
39+
I2C_ADDR_REG = 0xFF
40+
41+
42+
class SCALESUnit:
43+
def __init__(self, i2c: Union[I2C, PAHUBUnit], addr = SCALES_ADDR) -> None:
44+
self.i2c = i2c
45+
self.i2c_addr = addr
46+
self._available()
47+
48+
def _available(self) -> None:
49+
if not (self.i2c_addr in self.i2c.scan()):
50+
raise UnitError("Scales unit maybe not connect")
51+
52+
def get_button_status(self, status) -> int:
53+
status += BUTTON_SHORT
54+
if status >= BUTTON_SHORT and status <= BUTTON_OFFSET:
55+
return self.i2c.readfrom_mem(self.i2c_addr, status, 1)[0]
56+
57+
def set_button_offset(self, enable) -> None:
58+
self.i2c.writeto_mem(self.i2c_addr, BUTTON_OFFSET, bytes([enable]))
59+
60+
def set_rgbled_sync(self, control) -> None:
61+
self.i2c.writeto_mem(self.i2c_addr, LED_SYNC, bytes([control]))
62+
63+
def get_rgbled_sync(self) -> int:
64+
return self.i2c.readfrom_mem(self.i2c_addr, LED_SYNC, 1)[0]
65+
66+
def set_rgb_led(self, rgb) -> None:
67+
self.i2c.writeto_mem(self.i2c_addr, LED_RED, rgb.to_bytes(3, 'big'))
68+
69+
def get_rgb_led(self) -> list:
70+
return list(self.i2c.readfrom_mem(self.i2c_addr, LED_RED, 3))
71+
72+
def get_scale_value(self, scale) -> int:
73+
scale = RAW_ADC + (scale * 4)
74+
if scale >= RAW_ADC and scale <= OFFSET_ADC:
75+
byte_val = self.i2c.readfrom_mem(self.i2c_addr, scale, 4)
76+
if scale == GET_WEIGHT:
77+
return int((struct.unpack('>i', byte_val)[0]) /100)
78+
return struct.unpack('>i', byte_val)[0]
79+
80+
def set_raw_offset(self, value) -> None:
81+
self.i2c.writeto_mem(self.i2c_addr, OFFSET_ADC, value.to_bytes(4, 'big'))
82+
83+
def set_current_raw_offset(self) -> None:
84+
self.i2c.writeto_mem(self.i2c_addr, SOFT_OFFSET, bytes([1]))
85+
86+
def set_calibration_zero(self) -> None:
87+
self.i2c.writeto_mem(self.i2c_addr, CALI_ZERO, bytes([0,0]))
88+
time.sleep_ms(200)
89+
90+
def set_calibration_load(self, gram) -> None:
91+
self.i2c.writeto_mem(self.i2c_addr, CALI_LOAD, gram.to_bytes(2, 'little'))
92+
time.sleep_ms(200)
93+
94+
def get_device_inform(self, mode) -> int:
95+
if mode >= FW_VER_REG and mode <= I2C_ADDR_REG:
96+
return self.i2c.readfrom_mem(self.i2c_addr, mode, 1)[0]
97+
98+
def set_i2c_address(self, addr):
99+
if addr >= 1 and addr <= 127:
100+
if addr != self.i2c_addr:
101+
self.i2c.writeto_mem(self.i2c_addr, I2C_ADDR_REG, bytes([addr]))
102+
self.i2c_addr = addr
103+
time.sleep_ms(200)
104+

0 commit comments

Comments
 (0)