3
3
import struct
4
4
from machine import I2C
5
5
import _thread
6
- from time import sleep_ms
6
+ from time import sleep_ms , ticks_ms , ticks_diff
7
7
8
8
from ucPack import ucPack
9
9
15
15
16
16
17
17
class ArduinoAlvik :
18
-
19
18
_update_thread_running = False
20
19
_update_thread_id = None
21
20
_touch_events_thread_running = False
@@ -31,10 +30,10 @@ def __init__(self):
31
30
self .left_wheel = _ArduinoAlvikWheel (self ._packeter , ord ('L' ))
32
31
self .right_wheel = _ArduinoAlvikWheel (self ._packeter , ord ('R' ))
33
32
self ._led_state = list ((None ,))
34
- self .left_led = _ArduinoAlvikRgbLed (self ._packeter , 'left' , self ._led_state ,
35
- rgb_mask = [0b00000100 , 0b00001000 , 0b00010000 ])
36
- self .right_led = _ArduinoAlvikRgbLed (self ._packeter , 'right' , self ._led_state ,
37
- rgb_mask = [0b00100000 , 0b01000000 , 0b10000000 ])
33
+ self .left_led = self . DL1 = _ArduinoAlvikRgbLed (self ._packeter , 'left' , self ._led_state ,
34
+ rgb_mask = [0b00000100 , 0b00001000 , 0b00010000 ])
35
+ self .right_led = self . DL2 = _ArduinoAlvikRgbLed (self ._packeter , 'right' , self ._led_state ,
36
+ rgb_mask = [0b00100000 , 0b01000000 , 0b10000000 ])
38
37
self ._battery_perc = None
39
38
self ._touch_byte = None
40
39
self ._behaviour = None
@@ -67,7 +66,8 @@ def __init__(self):
67
66
self ._bottom_tof = None
68
67
self ._linear_velocity = None
69
68
self ._angular_velocity = None
70
- self ._last_ack = ''
69
+ self ._last_ack = None
70
+ self ._waiting_ack = None
71
71
self ._version = [None , None , None ]
72
72
self ._touch_events = _ArduinoAlvikTouchEvents ()
73
73
@@ -131,7 +131,7 @@ def _idle(self, delay_=1, check_on_thread=False) -> None:
131
131
LEDR .value (led_val )
132
132
LEDG .value (1 )
133
133
led_val = (led_val + 1 ) % 2
134
- print ("Alvik is on" )
134
+ print ("********** Alvik is on ********** " )
135
135
except KeyboardInterrupt :
136
136
self .stop ()
137
137
sys .exit ()
@@ -176,7 +176,7 @@ def begin(self) -> int:
176
176
:return:
177
177
"""
178
178
if not self .is_on ():
179
- print ("\n Turn on your Arduino Alvik!\n " )
179
+ print ("\n ********** Please turn on your Arduino Alvik! ********** \n " )
180
180
sleep_ms (1000 )
181
181
self ._idle (1000 )
182
182
self ._begin_update_thread ()
@@ -199,6 +199,7 @@ def _wait_for_ack(self) -> None:
199
199
Waits until receives 0x00 ack from robot
200
200
:return:
201
201
"""
202
+ self ._waiting_ack = 0x00
202
203
while self ._last_ack != 0x00 :
203
204
sleep_ms (20 )
204
205
@@ -229,24 +230,31 @@ def _stop_update_thread(cls):
229
230
"""
230
231
cls ._update_thread_running = False
231
232
232
- def _wait_for_target (self ):
233
- while not self .is_target_reached ():
234
- pass
233
+ def _wait_for_target (self , idle_time ):
234
+ start = ticks_ms ()
235
+ while True :
236
+ if ticks_diff (ticks_ms (), start ) >= idle_time * 1000 and self .is_target_reached ():
237
+ break
238
+ else :
239
+ # print(self._last_ack)
240
+ sleep_ms (100 )
235
241
236
242
def is_target_reached (self ) -> bool :
237
243
"""
238
244
Returns True if robot has sent an M or R acknowledgment.
239
245
It also responds with an ack received message
240
246
:return:
241
247
"""
242
- if self ._last_ack != ord ('M' ) and self ._last_ack != ord ('R' ):
243
- sleep_ms (50 )
244
- return False
245
- else :
248
+ if self ._waiting_ack is None :
249
+ return True
250
+ if self ._last_ack == self ._waiting_ack :
246
251
self ._packeter .packetC1B (ord ('X' ), ord ('K' ))
247
252
uart .write (self ._packeter .msg [0 :self ._packeter .msg_size ])
248
- sleep_ms (200 )
253
+ sleep_ms (100 )
254
+ self ._last_ack = 0x00
255
+ self ._waiting_ack = None
249
256
return True
257
+ return False
250
258
251
259
def set_behaviour (self , behaviour : int ):
252
260
"""
@@ -269,8 +277,9 @@ def rotate(self, angle: float, unit: str = 'deg', blocking: bool = True):
269
277
sleep_ms (200 )
270
278
self ._packeter .packetC1F (ord ('R' ), angle )
271
279
uart .write (self ._packeter .msg [0 :self ._packeter .msg_size ])
280
+ self ._waiting_ack = ord ('R' )
272
281
if blocking :
273
- self ._wait_for_target ()
282
+ self ._wait_for_target (idle_time = ( angle / MOTOR_CONTROL_DEG_S ) )
274
283
275
284
def move (self , distance : float , unit : str = 'cm' , blocking : bool = True ):
276
285
"""
@@ -284,8 +293,9 @@ def move(self, distance: float, unit: str = 'cm', blocking: bool = True):
284
293
sleep_ms (200 )
285
294
self ._packeter .packetC1F (ord ('G' ), distance )
286
295
uart .write (self ._packeter .msg [0 :self ._packeter .msg_size ])
296
+ self ._waiting_ack = ord ('M' )
287
297
if blocking :
288
- self ._wait_for_target ()
298
+ self ._wait_for_target (idle_time = ( distance / MOTOR_CONTROL_MM_S ) )
289
299
290
300
def stop (self ):
291
301
"""
@@ -610,7 +620,11 @@ def _parse_message(self) -> int:
610
620
_ , self ._linear_velocity , self ._angular_velocity = self ._packeter .unpacketC2F ()
611
621
elif code == ord ('x' ):
612
622
# robot ack
613
- _ , self ._last_ack = self ._packeter .unpacketC1B ()
623
+ if self ._waiting_ack is not None :
624
+ _ , self ._last_ack = self ._packeter .unpacketC1B ()
625
+ else :
626
+ self ._packeter .unpacketC1B ()
627
+ self ._last_ack = 0x00
614
628
elif code == ord ('z' ):
615
629
# robot ack
616
630
_ , self ._x , self ._y , self ._theta = self ._packeter .unpacketC3F ()
@@ -899,9 +913,9 @@ def hsv2label(h, s, v) -> str:
899
913
label = 'GREEN'
900
914
elif 170 <= h < 210 :
901
915
label = 'LIGHT BLUE'
902
- elif 210 <= h < 260 :
916
+ elif 210 <= h < 250 :
903
917
label = 'BLUE'
904
- elif 260 <= h < 280 :
918
+ elif 250 <= h < 280 :
905
919
label = 'VIOLET'
906
920
else : # h<20 or h>=280 is more problematic
907
921
if v < 0.5 and s < 0.45 :
@@ -1322,3 +1336,44 @@ def register_callback(self, event_name: str, callback: callable, args: tuple = N
1322
1336
if event_name not in self .__class__ .available_events :
1323
1337
return
1324
1338
super ().register_callback (event_name , callback , args )
1339
+
1340
+
1341
+ # UPDATE FIRMWARE METHOD #
1342
+
1343
+ def update_firmware (file_path : str ):
1344
+ """
1345
+
1346
+ :param file_path: path of your FW bin
1347
+ :return:
1348
+ """
1349
+
1350
+ from sys import exit
1351
+ from stm32_flash import (
1352
+ CHECK_STM32 ,
1353
+ STM32_endCommunication ,
1354
+ STM32_startCommunication ,
1355
+ STM32_NACK ,
1356
+ STM32_eraseMEM ,
1357
+ STM32_writeMEM , )
1358
+
1359
+ if CHECK_STM32 .value () is not 1 :
1360
+ print ("Turn on your Alvik to continue..." )
1361
+ while CHECK_STM32 .value () is not 1 :
1362
+ sleep_ms (500 )
1363
+
1364
+ ans = STM32_startCommunication ()
1365
+ if ans == STM32_NACK :
1366
+ print ("Cannot establish connection with STM32" )
1367
+ exit (- 1 )
1368
+
1369
+ print ('\n STM32 FOUND' )
1370
+
1371
+ print ('\n ERASING MEM' )
1372
+ STM32_eraseMEM (0xFFFF )
1373
+
1374
+ print ("\n WRITING MEM" )
1375
+ STM32_writeMEM (file_path )
1376
+ print ("\n DONE" )
1377
+ print ("\n Lower Boot0 and reset STM32" )
1378
+
1379
+ STM32_endCommunication ()
0 commit comments