Skip to content

Commit cc70cd1

Browse files
committed
feature/module/4Relay: 4-channel mechanical relays
1 parent dddd3cc commit cc70cd1

File tree

4 files changed

+107
-0
lines changed

4 files changed

+107
-0
lines changed

m5stack/libs/module/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
_attrs = {
55
"DualKmeter": "dual_kmeter",
6+
"Relay4": "relay_4",
67
}
78

89
# Lazy loader, effectively does:

m5stack/libs/module/manifest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"__init__.py",
55
"dual_kmeter.py",
66
"mbus.py",
7+
"relay_4.py",
8+
"module_helper.py",
79
),
810
base_path="..",
911
opt=0,

m5stack/libs/module/module_helper.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# -*- encoding: utf-8 -*-
2+
3+
4+
class ModuleError(Exception):
5+
pass

m5stack/libs/module/relay_4.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
from .mbus import i2c1
2+
from .module_helper import ModuleError
3+
import struct
4+
import time
5+
6+
DEV_I2C_ADDR = 0x26
7+
RELAY_REG = 0x10
8+
ADC_8BIT_REG = 0x20
9+
ADC_16BIT_REG = 0x30
10+
I2C_ADDR_REG = 0xFF
11+
12+
class Relay_Stack:
13+
14+
def __init__(self, i2c, addr):
15+
self.i2c = i2c
16+
self.i2c_addr = addr
17+
18+
def _available(self):
19+
if not (self.i2c_addr in self.i2c.scan()):
20+
raise ModuleError("4 relay module maybe not connect")
21+
22+
def get_relay_status(self, num):
23+
"""
24+
get RELAY Status.
25+
reg: 0x10
26+
num: select only 1 to 4
27+
return 0 or 1
28+
"""
29+
num = min(4, max(num, 1))
30+
return ((self.i2c.readfrom_mem(self.i2c_addr, RELAY_REG, 1)[0] >> (num - 1)) & 0x01)
31+
32+
def set_relay_state(self, num, state):
33+
"""
34+
Set RELAY State.
35+
reg: 0x10
36+
num: select only 1 to 4
37+
state: value is 0 or 1
38+
"""
39+
num = min(4, max(num, 1))
40+
data = self.i2c.readfrom_mem(self.i2c_addr, RELAY_REG, 1)[0]
41+
if state:
42+
data |= (0x01 << (num - 1))
43+
else:
44+
data &= ~(0x01 << (num - 1))
45+
self.i2c.writeto_mem(self.i2c_addr, RELAY_REG, bytes([data]))
46+
47+
def set_all_relay_state(self, state):
48+
"""
49+
Set All RELAY State.
50+
reg: 0x10
51+
state: value is 0 or 1
52+
"""
53+
state = min(1, max(state, 0))
54+
data = 0x0f if state else 0x00
55+
self.i2c.writeto_mem(self.i2c_addr, RELAY_REG, bytes([data]))
56+
57+
#************************# Version 1.1 #****************************#
58+
def get_adc_8bit_value(self, volt=0):
59+
"""
60+
get adc raw/volt 8bit value
61+
"""
62+
val = self.i2c.readfrom_mem(self.i2c_addr, ADC_8BIT_REG, 1)[0]
63+
if volt:
64+
val = (3.3/255) * val * 8
65+
return round(val, 2)
66+
else:
67+
return val
68+
69+
def get_adc_12bit_value(self, volt=0):
70+
"""
71+
get adc raw/volt 12bit value
72+
"""
73+
buf = self.i2c.readfrom_mem(self.i2c_addr, ADC_16BIT_REG, 2)
74+
val = struct.unpack('<H', buf)[0]
75+
if volt:
76+
val = (3.3/4095) * val * 8
77+
return round(val, 2)
78+
else:
79+
return val
80+
81+
def set_i2c_address(self, addr):
82+
"""
83+
set i2c address.
84+
addr : 1 to 127
85+
"""
86+
if addr >= 1 and addr <= 127:
87+
if addr != self.i2c_addr:
88+
self.i2c.writeto_mem(self.i2c_addr, I2C_ADDR_REG, bytes([addr]))
89+
self.i2c_addr = addr
90+
time.sleep_ms(100)
91+
92+
#*******************************************************************#
93+
94+
class Relay4(Relay_Stack):
95+
96+
def __init__(self, address: int = DEV_I2C_ADDR):
97+
super().__init__(i2c1, address)
98+
self._available()
99+

0 commit comments

Comments
 (0)