@@ -19,6 +19,8 @@ class ArduinoAlvik:
19
19
20
20
_update_thread_running = False
21
21
_update_thread_id = None
22
+ _touch_events_thread_running = False
23
+ _touch_events_thread_id = None
22
24
23
25
def __new__ (cls ):
24
26
if not hasattr (cls , '_instance' ):
@@ -68,6 +70,7 @@ def __init__(self):
68
70
self ._angular_velocity = None
69
71
self ._last_ack = ''
70
72
self ._version = [None , None , None ]
73
+ self ._touch_events = _ArduinoAlvikTouchEvents ()
71
74
72
75
@staticmethod
73
76
def is_on () -> bool :
@@ -135,7 +138,7 @@ def _idle(self, delay_=1, check_on_thread=False) -> None:
135
138
sys .exit ()
136
139
except Exception as e :
137
140
pass
138
- #print(f'Unable to read SOC: {e}')
141
+ # print(f'Unable to read SOC: {e}')
139
142
finally :
140
143
LEDR .value (1 )
141
144
LEDG .value (1 )
@@ -179,6 +182,9 @@ def begin(self) -> int:
179
182
self ._idle (1000 )
180
183
self ._begin_update_thread ()
181
184
sleep_ms (100 )
185
+ if self ._touch_events .has_callbacks ():
186
+ print ('Starting touch events' )
187
+ self ._start_touch_events_thread ()
182
188
self ._reset_hw ()
183
189
self ._flush_uart ()
184
190
self ._snake_robot (1000 )
@@ -293,9 +299,12 @@ def stop(self):
293
299
# turn off UI leds
294
300
self ._set_leds (0x00 )
295
301
296
- # stop the update thrad
302
+ # stop the update thread
297
303
self ._stop_update_thread ()
298
304
305
+ # stop touch events thread
306
+ self ._stop_touch_events_thread ()
307
+
299
308
# delete _instance
300
309
del self .__class__ ._instance
301
310
gc .collect ()
@@ -953,6 +962,99 @@ def print_status(self):
953
962
continue
954
963
print (f'{ str (a ).upper ()} = { getattr (self , str (a ))} ' )
955
964
965
+ def on_touch_ok_pressed (self , callback : callable , args : tuple = ()) -> None :
966
+ """
967
+ Register callback when touch button OK is pressed
968
+ :param callback:
969
+ :param args:
970
+ :return:
971
+ """
972
+ self ._touch_events .register_callback ('on_ok_pressed' , callback , args )
973
+
974
+ def on_touch_cancel_pressed (self , callback : callable , args : tuple = ()) -> None :
975
+ """
976
+ Register callback when touch button CANCEL is pressed
977
+ :param callback:
978
+ :param args:
979
+ :return:
980
+ """
981
+ self ._touch_events .register_callback ('on_cancel_pressed' , callback , args )
982
+
983
+ def on_touch_center_pressed (self , callback : callable , args : tuple = ()) -> None :
984
+ """
985
+ Register callback when touch button CENTER is pressed
986
+ :param callback:
987
+ :param args:
988
+ :return:
989
+ """
990
+ self ._touch_events .register_callback ('on_center_pressed' , callback , args )
991
+
992
+ def on_touch_up_pressed (self , callback : callable , args : tuple = ()) -> None :
993
+ """
994
+ Register callback when touch button UP is pressed
995
+ :param callback:
996
+ :param args:
997
+ :return:
998
+ """
999
+ self ._touch_events .register_callback ('on_up_pressed' , callback , args )
1000
+
1001
+ def on_touch_left_pressed (self , callback : callable , args : tuple = ()) -> None :
1002
+ """
1003
+ Register callback when touch button LEFT is pressed
1004
+ :param callback:
1005
+ :param args:
1006
+ :return:
1007
+ """
1008
+ self ._touch_events .register_callback ('on_left_pressed' , callback , args )
1009
+
1010
+ def on_touch_down_pressed (self , callback : callable , args : tuple = ()) -> None :
1011
+ """
1012
+ Register callback when touch button DOWN is pressed
1013
+ :param callback:
1014
+ :param args:
1015
+ :return:
1016
+ """
1017
+ self ._touch_events .register_callback ('on_down_pressed' , callback , args )
1018
+
1019
+ def on_touch_right_pressed (self , callback : callable , args : tuple = ()) -> None :
1020
+ """
1021
+ Register callback when touch button RIGHT is pressed
1022
+ :param callback:
1023
+ :param args:
1024
+ :return:
1025
+ """
1026
+ self ._touch_events .register_callback ('on_right_pressed' , callback , args )
1027
+
1028
+ def _start_touch_events_thread (self ) -> None :
1029
+ """
1030
+ Starts the touch events thread
1031
+ :return:
1032
+ """
1033
+ if not self .__class__ ._touch_events_thread_running :
1034
+ self .__class__ ._touch_events_thread_running = True
1035
+ self .__class__ ._touch_events_thread_id = _thread .start_new_thread (self ._update_touch_events , (50 ,))
1036
+
1037
+ def _update_touch_events (self , delay_ : int = 100 ):
1038
+ """
1039
+ Updates the touch state so that touch events can be generated
1040
+ :param delay_:
1041
+ :return:
1042
+ """
1043
+ while True :
1044
+ if self .is_on () and self ._touch_byte is not None :
1045
+ self ._touch_events .update_touch_state (self ._touch_byte )
1046
+ if not ArduinoAlvik ._touch_events_thread_running :
1047
+ break
1048
+ sleep_ms (delay_ )
1049
+
1050
+ @classmethod
1051
+ def _stop_touch_events_thread (cls ):
1052
+ """
1053
+ Stops the touch events thread
1054
+ :return:
1055
+ """
1056
+ cls ._touch_events_thread_running = False
1057
+
956
1058
957
1059
class _ArduinoAlvikWheel :
958
1060
@@ -1065,3 +1167,159 @@ def set_color(self, red: bool, green: bool, blue: bool):
1065
1167
self ._led_state [0 ] = led_status
1066
1168
self ._packeter .packetC1B (ord ('L' ), led_status & 0xFF )
1067
1169
uart .write (self ._packeter .msg [0 :self ._packeter .msg_size ])
1170
+
1171
+
1172
+ class _ArduinoAlvikEvents :
1173
+ """
1174
+ This is a generic events class
1175
+ """
1176
+
1177
+ def __init__ (self ):
1178
+ self ._callbacks = dict ()
1179
+
1180
+ def register_callback (self , event_name : str , callback : callable , args : tuple = None ):
1181
+ """
1182
+ Registers a callback to execute on an event
1183
+ :param event_name:
1184
+ :param callback: the callable
1185
+ :param args: arguments tuple to pass to the callable. remember the comma! (value,)
1186
+ :return:
1187
+ """
1188
+ self ._callbacks [event_name ] = (callback , args ,)
1189
+
1190
+ def has_callbacks (self ) -> bool :
1191
+ """
1192
+ True if the _callbacks dictionary has any callback registered
1193
+ :return:
1194
+ """
1195
+ return bool (self ._callbacks )
1196
+
1197
+ def execute_callback (self , event_name : str ):
1198
+ """
1199
+ Executes the callback associated to the event_name
1200
+ :param event_name:
1201
+ :return:
1202
+ """
1203
+ if event_name not in self ._callbacks .keys ():
1204
+ return
1205
+ self ._callbacks [event_name ][0 ](* self ._callbacks [event_name ][1 ])
1206
+
1207
+
1208
+ class _ArduinoAlvikTouchEvents (_ArduinoAlvikEvents ):
1209
+ """
1210
+ This is the event class to handle touch button events
1211
+ """
1212
+
1213
+ available_events = ['on_ok_pressed' , 'on_cancel_pressed' ,
1214
+ 'on_center_pressed' , 'on_left_pressed' ,
1215
+ 'on_right_pressed' , 'on_up_pressed' ,
1216
+ 'on_down_pressed' ]
1217
+
1218
+ def __init__ (self ):
1219
+ self ._current_touch_state = 0
1220
+ super ().__init__ ()
1221
+
1222
+ @staticmethod
1223
+ def _is_ok_pressed (current_state , new_state ) -> bool :
1224
+ """
1225
+ True if OK was pressed
1226
+ :param current_state:
1227
+ :param new_state:
1228
+ :return:
1229
+ """
1230
+ return not bool (current_state & 0b00000010 ) and bool (new_state & 0b00000010 )
1231
+
1232
+ @staticmethod
1233
+ def _is_cancel_pressed (current_state , new_state ) -> bool :
1234
+ """
1235
+ True if CANCEL was pressed
1236
+ :param current_state:
1237
+ :param new_state:
1238
+ :return:
1239
+ """
1240
+ return not bool (current_state & 0b00000100 ) and bool (new_state & 0b00000100 )
1241
+
1242
+ @staticmethod
1243
+ def _is_center_pressed (current_state , new_state ) -> bool :
1244
+ """
1245
+ True if CENTER was pressed
1246
+ :param current_state:
1247
+ :param new_state:
1248
+ :return:
1249
+ """
1250
+ return not bool (current_state & 0b00001000 ) and bool (new_state & 0b00001000 )
1251
+
1252
+ @staticmethod
1253
+ def _is_up_pressed (current_state , new_state ) -> bool :
1254
+ """
1255
+ True if UP was pressed
1256
+ :param current_state:
1257
+ :param new_state:
1258
+ :return:
1259
+ """
1260
+ return not bool (current_state & 0b00010000 ) and bool (new_state & 0b00010000 )
1261
+
1262
+ @staticmethod
1263
+ def _is_left_pressed (current_state , new_state ) -> bool :
1264
+ """
1265
+ True if LEFT was pressed
1266
+ :param current_state:
1267
+ :param new_state:
1268
+ :return:
1269
+ """
1270
+ return not bool (current_state & 0b00100000 ) and bool (new_state & 0b00100000 )
1271
+
1272
+ @staticmethod
1273
+ def _is_down_pressed (current_state , new_state ) -> bool :
1274
+ """
1275
+ True if DOWN was pressed
1276
+ :param current_state:
1277
+ :param new_state:
1278
+ :return:
1279
+ """
1280
+ return not bool (current_state & 0b01000000 ) and bool (new_state & 0b01000000 )
1281
+
1282
+ @staticmethod
1283
+ def _is_right_pressed (current_state , new_state ) -> bool :
1284
+ """
1285
+ True if RIGHT was pressed
1286
+ :param current_state:
1287
+ :param new_state:
1288
+ :return:
1289
+ """
1290
+ return not bool (current_state & 0b10000000 ) and bool (new_state & 0b10000000 )
1291
+
1292
+ def update_touch_state (self , touch_state : int ):
1293
+ """
1294
+ Updates the internal touch state and executes any possible callback
1295
+ :param touch_state:
1296
+ :return:
1297
+ """
1298
+
1299
+ if self ._is_ok_pressed (self ._current_touch_state , touch_state ):
1300
+ self .execute_callback ('on_ok_pressed' )
1301
+
1302
+ if self ._is_cancel_pressed (self ._current_touch_state , touch_state ):
1303
+ self .execute_callback ('on_cancel_pressed' )
1304
+
1305
+ if self ._is_center_pressed (self ._current_touch_state , touch_state ):
1306
+ self .execute_callback ('on_center_pressed' )
1307
+
1308
+ if self ._is_up_pressed (self ._current_touch_state , touch_state ):
1309
+ self .execute_callback ('on_up_pressed' )
1310
+
1311
+ if self ._is_left_pressed (self ._current_touch_state , touch_state ):
1312
+ self .execute_callback ('on_left_pressed' )
1313
+
1314
+ if self ._is_down_pressed (self ._current_touch_state , touch_state ):
1315
+ self .execute_callback ('on_down_pressed' )
1316
+
1317
+ if self ._is_right_pressed (self ._current_touch_state , touch_state ):
1318
+ self .execute_callback ('on_right_pressed' )
1319
+
1320
+ self ._current_touch_state = touch_state
1321
+
1322
+ def register_callback (self , event_name : str , callback : callable , args : tuple = None ):
1323
+ if event_name not in self .__class__ .available_events :
1324
+ return
1325
+ super ().register_callback (event_name , callback , args )
0 commit comments