@@ -26,6 +26,7 @@ def __new__(cls):
26
26
return cls ._instance
27
27
28
28
def __init__ (self ):
29
+ self .i2c = _ArduinoAlvikI2C (A4 , A5 )
29
30
self ._packeter = ucPack (200 )
30
31
self .left_wheel = _ArduinoAlvikWheel (self ._packeter , ord ('L' ))
31
32
self .right_wheel = _ArduinoAlvikWheel (self ._packeter , ord ('R' ))
@@ -100,43 +101,50 @@ def _progress_bar(percentage: float) -> None:
100
101
word = marks_str + f" { percentage } % \t "
101
102
sys .stdout .write (bytes ((word .encode ('utf-8' ))))
102
103
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 :
104
111
"""
105
112
Alvik's idle mode behaviour
106
113
:return:
107
114
"""
108
-
109
115
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 )
111
122
led_val = 0
112
123
113
124
try :
114
125
while not self .is_on ():
115
126
if check_on_thread and not self .__class__ ._update_thread_running :
116
127
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 )
124
128
125
129
cmd = bytearray (1 )
126
130
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 ]
130
134
soc_perc = soc_raw * 0.00390625
131
135
self ._progress_bar (round (soc_perc ))
132
- sleep_ms (delay_ )
136
+ if blocking :
137
+ self ._lenghty_op (10000 )
138
+ else :
139
+ sleep_ms (delay_ )
133
140
if soc_perc > 97 :
134
141
LEDG .value (0 )
135
142
LEDR .value (1 )
136
143
else :
137
144
LEDR .value (led_val )
138
145
LEDG .value (1 )
139
146
led_val = (led_val + 1 ) % 2
147
+ self .i2c ._prio = False
140
148
print ("********** Alvik is on **********" )
141
149
except KeyboardInterrupt :
142
150
self .stop ()
@@ -148,6 +156,7 @@ def _idle(self, delay_=1, check_on_thread=False) -> None:
148
156
LEDR .value (1 )
149
157
LEDG .value (1 )
150
158
NANO_CHK .value (0 )
159
+ self .i2c ._prio = False
151
160
152
161
@staticmethod
153
162
def _snake_robot (duration : int = 1000 ):
@@ -582,7 +591,7 @@ def _update(self, delay_=1):
582
591
while True :
583
592
if not self .is_on ():
584
593
print ("Alvik is off" )
585
- self ._idle (1000 , check_on_thread = True )
594
+ self ._idle (1000 , check_on_thread = True , blocking = True )
586
595
self ._reset_hw ()
587
596
self ._flush_uart ()
588
597
sleep_ms (1000 )
@@ -1249,6 +1258,64 @@ def _stop_events_thread(cls):
1249
1258
cls ._events_thread_running = False
1250
1259
1251
1260
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
+
1252
1319
class _ArduinoAlvikServo :
1253
1320
1254
1321
def __init__ (self , packeter : ucPack , label : str , servo_id : int , position : list [int | None ]):
0 commit comments