Skip to content

Commit 5e0d2f6

Browse files
committed
feat: i2c exposed. if Alvik off bms has priority
1 parent acd885b commit 5e0d2f6

File tree

2 files changed

+84
-17
lines changed

2 files changed

+84
-17
lines changed

arduino_alvik/arduino_alvik.py

Lines changed: 82 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def __new__(cls):
2626
return cls._instance
2727

2828
def __init__(self):
29+
self.i2c = _ArduinoAlvikI2C(A4, A5)
2930
self._packeter = ucPack(200)
3031
self.left_wheel = _ArduinoAlvikWheel(self._packeter, ord('L'))
3132
self.right_wheel = _ArduinoAlvikWheel(self._packeter, ord('R'))
@@ -100,43 +101,50 @@ def _progress_bar(percentage: float) -> None:
100101
word = marks_str + f" {percentage}% \t"
101102
sys.stdout.write(bytes((word.encode('utf-8'))))
102103

103-
def _idle(self, delay_=1, check_on_thread=False) -> None:
104+
def _lenghty_op(self, iterations=10000000) -> int:
105+
result = 0
106+
for i in range(1, iterations):
107+
result += i * i
108+
return result
109+
110+
def _idle(self, delay_=1, check_on_thread=False, blocking=False) -> None:
104111
"""
105112
Alvik's idle mode behaviour
106113
:return:
107114
"""
108-
109115
NANO_CHK.value(1)
110-
sleep_ms(500)
116+
self.i2c._prio = True
117+
118+
if blocking:
119+
self._lenghty_op(50000)
120+
else:
121+
sleep_ms(500)
111122
led_val = 0
112123

113124
try:
114125
while not self.is_on():
115126
if check_on_thread and not self.__class__._update_thread_running:
116127
break
117-
_ESP32_SDA = Pin(A4, Pin.OUT)
118-
_ESP32_SCL = Pin(A5, Pin.OUT)
119-
_ESP32_SCL.value(1)
120-
_ESP32_SDA.value(1)
121-
sleep_ms(100)
122-
_ESP32_SCL.value(0)
123-
_ESP32_SDA.value(0)
124128

125129
cmd = bytearray(1)
126130
cmd[0] = 0x06
127-
i2c = I2C(0, scl=ESP32_SCL, sda=ESP32_SDA)
128-
i2c.writeto(0x36, cmd)
129-
soc_raw = struct.unpack('h', i2c.readfrom(0x36, 2))[0]
131+
self.i2c.writeto(0x36, cmd, start=True, priority=True)
132+
133+
soc_raw = struct.unpack('h', self.i2c.readfrom(0x36, 2, priority=True))[0]
130134
soc_perc = soc_raw * 0.00390625
131135
self._progress_bar(round(soc_perc))
132-
sleep_ms(delay_)
136+
if blocking:
137+
self._lenghty_op(10000)
138+
else:
139+
sleep_ms(delay_)
133140
if soc_perc > 97:
134141
LEDG.value(0)
135142
LEDR.value(1)
136143
else:
137144
LEDR.value(led_val)
138145
LEDG.value(1)
139146
led_val = (led_val + 1) % 2
147+
self.i2c._prio = False
140148
print("********** Alvik is on **********")
141149
except KeyboardInterrupt:
142150
self.stop()
@@ -148,6 +156,7 @@ def _idle(self, delay_=1, check_on_thread=False) -> None:
148156
LEDR.value(1)
149157
LEDG.value(1)
150158
NANO_CHK.value(0)
159+
self.i2c._prio = False
151160

152161
@staticmethod
153162
def _snake_robot(duration: int = 1000):
@@ -582,7 +591,7 @@ def _update(self, delay_=1):
582591
while True:
583592
if not self.is_on():
584593
print("Alvik is off")
585-
self._idle(1000, check_on_thread=True)
594+
self._idle(1000, check_on_thread=True, blocking=True)
586595
self._reset_hw()
587596
self._flush_uart()
588597
sleep_ms(1000)
@@ -1249,6 +1258,64 @@ def _stop_events_thread(cls):
12491258
cls._events_thread_running = False
12501259

12511260

1261+
class _ArduinoAlvikI2C:
1262+
1263+
def __init__(self, sda: int, scl: int):
1264+
"""
1265+
Alvik I2C wrapper
1266+
:param sda:
1267+
:param scl:
1268+
"""
1269+
self._lock = _thread.allocate_lock()
1270+
self._prio = False
1271+
self.sda = sda
1272+
self.scl = scl
1273+
1274+
def _start(self):
1275+
"""
1276+
Bitbanging start condition
1277+
:return:
1278+
"""
1279+
_SDA = Pin(self.sda, Pin.OUT)
1280+
_SDA.value(1)
1281+
sleep_ms(100)
1282+
_SDA.value(0)
1283+
1284+
def scan(self, start=False, priority=False):
1285+
"""
1286+
I2C scan method
1287+
:return:
1288+
"""
1289+
if not priority and self._prio:
1290+
return []
1291+
with self._lock:
1292+
if start:
1293+
self._start()
1294+
i2c = I2C(0, scl=Pin(self.scl, Pin.OUT), sda=Pin(self.sda, Pin.OUT))
1295+
out = i2c.scan()
1296+
return out
1297+
1298+
def readfrom(self, addr, nbytes, stop=True, start=False, priority=False):
1299+
if not priority and self._prio:
1300+
return None
1301+
with self._lock:
1302+
if start:
1303+
self._start()
1304+
i2c = I2C(0, scl=Pin(self.scl, Pin.OUT), sda=Pin(self.sda, Pin.OUT))
1305+
out = i2c.readfrom(addr, nbytes, stop)
1306+
return out
1307+
1308+
def writeto(self, addr, buf, stop=True, start=False, priority=False):
1309+
if not priority and self._prio:
1310+
return None
1311+
with self._lock:
1312+
if start:
1313+
self._start()
1314+
i2c = I2C(0, scl=Pin(self.scl, Pin.OUT), sda=Pin(self.sda, Pin.OUT))
1315+
out = i2c.writeto(addr, buf, stop)
1316+
return out
1317+
1318+
12521319
class _ArduinoAlvikServo:
12531320

12541321
def __init__(self, packeter: ucPack, label: str, servo_id: int, position: list[int | None]):

arduino_alvik/pinout_definitions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
RESET_STM32 = Pin(D3, Pin.OUT) # nano D3 -> STM32 NRST
1414
NANO_CHK = Pin(D4, Pin.OUT) # nano D4 -> STM32 NANO_CHK
1515
CHECK_STM32 = Pin(A6, Pin.IN, Pin.PULL_DOWN) # nano A6/D23 -> STM32 ROBOT_CHK
16-
ESP32_SDA = Pin(A4, Pin.OUT) # ESP32_SDA
17-
ESP32_SCL = Pin(A5, Pin.OUT) # ESP32_SCL
16+
# ESP32_SDA = Pin(A4, Pin.OUT) # ESP32_SDA
17+
# ESP32_SCL = Pin(A5, Pin.OUT) # ESP32_SCL
1818

1919
# LEDS
2020
LEDR = Pin(46, Pin.OUT) #RED ESP32 LEDR

0 commit comments

Comments
 (0)