33import struct
44from machine import I2C
55import _thread
6- from time import sleep_ms
6+ from time import sleep_ms , ticks_ms , ticks_diff
77
88from ucPack import ucPack
99
1515
1616
1717class ArduinoAlvik :
18-
1918 _update_thread_running = False
2019 _update_thread_id = None
2120 _touch_events_thread_running = False
@@ -31,10 +30,10 @@ def __init__(self):
3130 self .left_wheel = _ArduinoAlvikWheel (self ._packeter , ord ('L' ))
3231 self .right_wheel = _ArduinoAlvikWheel (self ._packeter , ord ('R' ))
3332 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 ])
3837 self ._battery_perc = None
3938 self ._touch_byte = None
4039 self ._behaviour = None
@@ -67,7 +66,8 @@ def __init__(self):
6766 self ._bottom_tof = None
6867 self ._linear_velocity = None
6968 self ._angular_velocity = None
70- self ._last_ack = ''
69+ self ._last_ack = None
70+ self ._waiting_ack = None
7171 self ._version = [None , None , None ]
7272 self ._touch_events = _ArduinoAlvikTouchEvents ()
7373
@@ -131,7 +131,7 @@ def _idle(self, delay_=1, check_on_thread=False) -> None:
131131 LEDR .value (led_val )
132132 LEDG .value (1 )
133133 led_val = (led_val + 1 ) % 2
134- print ("Alvik is on" )
134+ print ("********** Alvik is on ********** " )
135135 except KeyboardInterrupt :
136136 self .stop ()
137137 sys .exit ()
@@ -176,7 +176,7 @@ def begin(self) -> int:
176176 :return:
177177 """
178178 if not self .is_on ():
179- print ("\n Turn on your Arduino Alvik!\n " )
179+ print ("\n ********** Please turn on your Arduino Alvik! ********** \n " )
180180 sleep_ms (1000 )
181181 self ._idle (1000 )
182182 self ._begin_update_thread ()
@@ -199,6 +199,7 @@ def _wait_for_ack(self) -> None:
199199 Waits until receives 0x00 ack from robot
200200 :return:
201201 """
202+ self ._waiting_ack = 0x00
202203 while self ._last_ack != 0x00 :
203204 sleep_ms (20 )
204205
@@ -229,24 +230,31 @@ def _stop_update_thread(cls):
229230 """
230231 cls ._update_thread_running = False
231232
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 )
235241
236242 def is_target_reached (self ) -> bool :
237243 """
238244 Returns True if robot has sent an M or R acknowledgment.
239245 It also responds with an ack received message
240246 :return:
241247 """
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 :
246251 self ._packeter .packetC1B (ord ('X' ), ord ('K' ))
247252 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
249256 return True
257+ return False
250258
251259 def set_behaviour (self , behaviour : int ):
252260 """
@@ -269,8 +277,9 @@ def rotate(self, angle: float, unit: str = 'deg', blocking: bool = True):
269277 sleep_ms (200 )
270278 self ._packeter .packetC1F (ord ('R' ), angle )
271279 uart .write (self ._packeter .msg [0 :self ._packeter .msg_size ])
280+ self ._waiting_ack = ord ('R' )
272281 if blocking :
273- self ._wait_for_target ()
282+ self ._wait_for_target (idle_time = ( angle / MOTOR_CONTROL_DEG_S ) )
274283
275284 def move (self , distance : float , unit : str = 'cm' , blocking : bool = True ):
276285 """
@@ -284,8 +293,9 @@ def move(self, distance: float, unit: str = 'cm', blocking: bool = True):
284293 sleep_ms (200 )
285294 self ._packeter .packetC1F (ord ('G' ), distance )
286295 uart .write (self ._packeter .msg [0 :self ._packeter .msg_size ])
296+ self ._waiting_ack = ord ('M' )
287297 if blocking :
288- self ._wait_for_target ()
298+ self ._wait_for_target (idle_time = ( distance / MOTOR_CONTROL_MM_S ) )
289299
290300 def stop (self ):
291301 """
@@ -610,7 +620,11 @@ def _parse_message(self) -> int:
610620 _ , self ._linear_velocity , self ._angular_velocity = self ._packeter .unpacketC2F ()
611621 elif code == ord ('x' ):
612622 # 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
614628 elif code == ord ('z' ):
615629 # robot ack
616630 _ , self ._x , self ._y , self ._theta = self ._packeter .unpacketC3F ()
@@ -899,9 +913,9 @@ def hsv2label(h, s, v) -> str:
899913 label = 'GREEN'
900914 elif 170 <= h < 210 :
901915 label = 'LIGHT BLUE'
902- elif 210 <= h < 260 :
916+ elif 210 <= h < 250 :
903917 label = 'BLUE'
904- elif 260 <= h < 280 :
918+ elif 250 <= h < 280 :
905919 label = 'VIOLET'
906920 else : # h<20 or h>=280 is more problematic
907921 if v < 0.5 and s < 0.45 :
@@ -1322,3 +1336,44 @@ def register_callback(self, event_name: str, callback: callable, args: tuple = N
13221336 if event_name not in self .__class__ .available_events :
13231337 return
13241338 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